Tengo una pregunta sobre la gestión de memoria JVM (al menos para la de SUN).JVM devolviendo memoria a OS
Me gustaría saber cómo controlar el hecho de que la JVM devuelve la memoria no utilizada al sistema operativo (Windows en mi caso).
Escribí un programa simple de Java para ilustrar lo que esperaba. Ejecútelo con la opción -Dcom.sun.management.jmxremote para que también pueda supervisar el montón con jconsole, por ejemplo.
con el siguiente programa:
package fr.brouillard.jvm;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
public class MemoryFree {
private BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
private List<byte[]> usedMemory = new LinkedList<byte[]>();
private int totalMB = 0;
private int gcTimes = 0;
public void allocate(int howManyMB) {
usedMemory.add(new byte[howManyMB * 1024 * 1024]);
totalMB += howManyMB;
System.out.println(howManyMB + "MB allocated, total allocated: " +
totalMB + "MB");
}
public void free() {
usedMemory.clear();
}
public void gc() {
System.gc();
System.out.println("GC " + (++gcTimes) + " times");
}
public void waitAnswer(String msg) {
System.out.println("Press [enter]" + ((msg==null)?"":msg));
try {
reader.readLine();
} catch (IOException e) {
}
}
public static void main(String[] args) {
MemoryFree mf = new MemoryFree();
mf.waitAnswer(" to allocate memory");
mf.allocate(20);
mf.allocate(10);
mf.allocate(15);
mf.waitAnswer(" to free memory");
mf.free();
mf.waitAnswer(" to GC");
mf.gc();
mf.waitAnswer(" to GC");
mf.gc();
mf.waitAnswer(" to GC");
mf.gc();
mf.waitAnswer(" to GC");
mf.gc();
mf.waitAnswer(" to exit the program");
try {
mf.reader.close();
} catch (IOException e) {}
}
}
El montón interna es libre una vez finalizada la primera GC (lo que se espera), pero la memoria sólo se envía de nuevo al sistema operativo a partir del tercer GC. Después de la cuarta, la memoria asignada completa se envía de vuelta al sistema operativo.
Cómo configurar la JVM para controlar este comportamiento? De hecho, mi problema es que necesito ejecutar varias sesiones de clientes CITRIX en un servidor, pero me gustaría que las JVM en ejecución en el servidor liberen la memoria lo antes posible (tengo solo unas pocas funciones de memoria de alto consumo en mi aplicación) .
Si no se puede controlar este comportamiento, puedo dejarlo así y aumentar la memoria virtual del sistema operativo y dejar que el sistema operativo lo use como lo desee sin grandes problemas de rendimiento. Por ejemplo, ¿habría problemas para tener 10 procesos Java de 1 GB de memoria (con solo 100 MB de objetos asignados reales en el montón) en un servidor de 4 GB con memoria virtual suficiente, por supuesto.
Supongo que otras personas ya se enfrentaron a tales preguntas/problemas.
Gracias por su ayuda.
wow las etiquetas comieron por completo tu código –
He reformateado tu fragmento de código un poco para usar las funciones de resaltado de sintaxis de Stackoverflow. Espero que no te importe –
Gracias, no logré que se muestre correctamente. No estoy frustrado, sólo estoy aquí ;-) nueva –