À propos de la gestion mémoire de java

On peut légitimement se demander comment la JVM gère la mémoire dont elle n'a plus besoin. Certes, le Garbage collector permet à java de recycler la mémoire inutilisée, mais, à première vue, cette mémoire ne semble pas être libérée et rendue au système. Ça n'est pas forcément dramatique (elle est paginée sur le disque), mais enfin, ça fait de la swap en moins.

En réalité, la JVM est parfaitement capable de rendre de la mémoire au système. Mais elle n'est pas pressée. Un petit exemple ; le programme suivant acquiert quelques 800MO de mémoire, les "oublie", et boucle à l'infini.

import java.util.ArrayList;
public class MemoryTest {

        public static void affMem() {
           System.out.println("free  "+ Runtime.getRuntime().freeMemory()/ 1000000);
	   System.out.println("total "+ Runtime.getRuntime().totalMemory()/1000000);
        }

	public static void main(String[] args) {
	    affMem();
	    int taille= 200 * 1000000;
	    int tab[]= new int[taille];
	    for (int i=0; i < taille;i++) {
		tab[i]= i;
	    }
			
	    affMem();
	    try {
		Thread.sleep(10000);
	    } catch (InterruptedException e) {
		e.printStackTrace();
	    }
	    System.out.println("done with tab");	
	    tab= null;
	    affMem();		
	    for (int i=0; i < 20; i++)	
		try {
		    Thread.sleep(1000);
		} catch (InterruptedException e) {
		    e.printStackTrace();
		}			
	    tab= new int[20000];
	    //System.gc();	
	    System.out.println("apres gc ");
	    affMem();
	    while (true) {
		try {
		    Thread.sleep(1000);
		} catch (InterruptedException e) {
		    e.printStackTrace();
		}
	        affMem();
		//System.gc();
	        //affMem();	
	    }	
	}
}

Conclusion ?

Si on l'exécute tel quel sur un jdk 1.5 de sun, avec -Xmx2000m histoire d'avoir la place en mémoire. On lance top.

Après allocation du tableau, VmRss= 793332. Affichage: free 4, total 805. La mémoire est allouée
On part laisse tourner, il est 8h40
On revient à 18h35. La mémoire utilisée a un peu baissé, mais pas beaucoup. 770896
On travaille sur l'ordinateur. à 18h56, la mémoire utilisée par la jvm est descendue à 551192
à 23H45, elle est rendue à 174116.

En forçant le GC, le phénomène est beaucoup plus rapide et plus net.

Donc java sait bien rendre de la mémoire au système.
Ouf!