我有一个关于JVM内存管理的问题(至少是针对SUN的)。
我想知道如何控制JVM将未使用的内存发送回操作系统(在我的情况下是Windows)。
我编写了一个简单的Java程序来说明我的期望。使用-Dcom.sun.management.jmxremote选项运行它,这样您可以使用jconsole等工具监视堆。
以下是程序内容:
我想知道如何控制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) {}
}
}
第一次进行垃圾回收后,内部堆会被释放(这是期望的),但只有在第三次垃圾回收后,内存才开始被发送回操作系统。在第四次之后,全部分配的内存都会被发送回操作系统。
如何设置JVM以控制此行为? 实际上,我的问题是我需要在服务器上运行多个CITRIX客户端会话,但我希望服务器上运行的JVM尽快释放内存(我的应用程序中只有少量高消耗内存的函数)。
如果无法控制此行为,我可以将其保留并增加操作系统虚拟内存,并让操作系统按照自己的方式使用它,而不会出现性能问题。 例如,在具有足够虚拟内存的4GB服务器上运行10个占用1GB内存的Java进程(仅具有100MB实际分配对象在堆中),是否会存在问题。
我想其他人已经遇到过这样的问题/困境。
谢谢您的帮助。