2008-11-27 10 views
8

Estoy ejecutando JVM 1.5.0 (predeterminado de Mac OS X) y estoy supervisando mi programa Java en el Monitor de actividad. Tengo el siguiente:Java todavía utiliza la memoria del sistema después de la desasignación de objetos y la recolección de basura

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.Date; 

public class MemoryTest { 

public static void memoryUsage() { 
System.out.println(
    Runtime.getRuntime().totalMemory() - 
    Runtime.getRuntime().freeMemory() 
); 
} 

public static void main(String[] args) throws IOException { 

    /* create a list */ 
    ArrayList<Date> list = new ArrayList<Date>(); 

    /* fill it with lots of data */ 
    for (int i = 0; i < 5000000; i++) { 
     list.add(new Date()); 
    } // systems shows ~164 MB of physical being used 

    /* clear it */ 
    memoryUsage();  // about 154 MB 
    list.clear(); 
    list = null; 
    System.gc(); 
    memoryUsage();  // about 151 KB, garbage collector worked 

    // system still shows 164 MB of physical being used. 
    System.out.println("Press enter to end..."); 
    BufferedReader br = new BufferedReader( 
      new InputStreamReader(System.in) 
      ); 
    br.readLine(); 
} 

}

Así que ¿por qué no la memoria física obtener liberados a pesar de que el recolector de basura parece funcionar bien?

+0

que el sistema operativo tiene un sistema de memoria virtual. La JVM no se aferra a la memoria física. Supongo que realmente quiere decir, ¿por qué la JVM no restringe el rango de direcciones virtuales que utiliza? – Raedwald

Respuesta

19

Muchas JVM nunca devuelven memoria al sistema operativo. Si lo hace o no, es específico de la implementación. Para aquellos que no lo hacen, los límites de memoria especificados al inicio, generalmente a través del indicador -Xmx, son los principales medios para reservar memoria para otras aplicaciones.

Estoy teniendo un tiempo difícil encontrar documentación sobre este tema, pero la garbage collector documentation for Sun's Java 5 aborda esta, lo que sugiere que bajo las condiciones adecuadas, la pila se reducirá si el colector correcta se utiliza — por defecto, si más que el 70% de el montón es gratis, se encogerá de modo que solo el 40% es gratis. Las opciones de línea de comando para controlar estos son -XX:MinHeapFreeRatio y -XX:MaxHeapFreeRatio.

+0

Tengo una aclaración aquí. En el caso de prueba particular anterior, al llamar a System.gc se liberará algo de memoria incluso si la lista de comentarios no es clara y nula. Aquí la lista está activa, por lo que la memoria se congela – UVM

0

Es posible que el sistema operativo muestre la memoria que actualmente está asignada al programa. Aunque se asignan 150 ~ MB, no significa que se están utilizando 150 ~ MB.

3

Debe utilizar un generador de perfiles específico de JVM para supervisar el espacio de montón real que está utilizando el programa en lugar de la memoria asignada a la JVM.

La JVM no solo es reacia a liberar la memoria del montón que asignó, sino que tiende a engullir espacio por diferentes motivos, incluida la compilación justo a tiempo.

5

Hay varias opciones de línea de comandos para la JVM que ayudan a ajustar el tamaño del montón utilizado por Java. Todo el mundo sabe (o debería saber) sobre -Xms y -Xmx, que establece el tamaño mínimo y máximo del montón.

Pero también está -XX: MinHeapFreeRatio y -XX: MaxHeapFreeRatio, que son los límites respectivos entre los que la JVM gestiona el espacio libre. Hace esto reduciendo el montón utilizado y puede reducir el consumo de memoria del programa.

Puede encontrar más información aquí:

Cuestiones relacionadas