JVM 将内存发送回操作系统
我有一个关于JVM内存管理的问题(至少对于SUN的内存管理)。
我想知道如何控制JVM将未使用的内存发送回操作系统(在我的情况下是Windows)的事实。
我写了一个简单的java程序来说明我的期望。使用 -Dcom.sun.management.jmxremote 选项运行它,以便您也可以使用 jconsole 等方式监视堆。
使用以下程序:
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) {}
}
}
一旦第一个GC完成,内部堆就可用了(这是预期的),但内存仅从第三个GC开始发送回操作系统。在第四个之后,将分配的内存全部发送回操作系统。
如何设置 JVM 来控制此行为?事实上,我的问题是我需要在服务器上运行多个CITRIX客户端会话,但我希望服务器上正在运行的JVM尽快释放内存(我的应用程序中只有很少的高消耗内存功能)。
如果这种行为无法控制,我是否可以让它这样,而是增加操作系统的虚拟内存,让操作系统按照自己的意愿使用它,而不会出现明显的性能问题。例如,当然,在具有足够虚拟内存的4GB服务器上具有10个1GB内存的java进程(堆中只有100MB的实际分配对象)是否会有问题。
我猜其他人已经面临这样的问题/问题。
感谢您的帮助。