【发布时间】:2010-10-15 02:31:52
【问题描述】:
我有一个关于 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 实际分配的对象)会不会有问题。
我猜其他人已经面临这样的问题/问题。
感谢您的帮助。
【问题讨论】:
-
哇,标签完全吃掉了你的代码
-
我已经稍微重新格式化了你的代码 sn-p 以使用 Stackoverflow 的语法高亮功能——我希望你不介意
-
谢谢,我未能正确显示它。我并不沮丧,我只是新来的 ;-)
-
一个老问题,但我也希望看到更好的人机工程学或至少外部控制的 JVM 堆提示,以便更好地控制多个 JVM 实例及其各自的资源。
标签: java memory-management jvm