java JVM 将内存发送回操作系统
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/675589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JVM sending back memory to OS
提问by Matthieu BROUILLARD
I have a question regarding the JVM memory management (at least for the SUN's one).
我有一个关于 JVM 内存管理的问题(至少对于 SUN 的)。
I would like to know how to control the fact that the JVM send the unused memory back to the OS (windows in my case).
我想知道如何控制 JVM 将未使用的内存发送回操作系统(在我的情况下为 Windows)这一事实。
I wrote a simple java program to illustrate what I expect. Run it with -Dcom.sun.management.jmxremote option so that you can also monitor the heap with jconsole for example.
我写了一个简单的java程序来说明我的期望。使用 -Dcom.sun.management.jmxremote 选项运行它,以便您还可以使用 jconsole 监视堆。
With the following program:
使用以下程序:
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) {}
}
}
The internal heap is free once the first GC is done (what is expected) but the memory is only sent back to the OS starting from the third GC. After the fourth, the full allocated memory is sent back to the OS.
第一次 GC 完成后,内部堆是空闲的(这是预期的),但内存仅从第三次 GC 开始发送回操作系统。第四次之后,全部分配的内存被发送回操作系统。
How to setup the JVM to control this behaviour? In fact my problem is that I need to run several CITRIX clients sessions on a server, but I would like the running JVMs on the server to free the memory as soon as possible (I have only few high consuming memory functions in my application).
如何设置 JVM 来控制这种行为?实际上,我的问题是我需要在服务器上运行多个 CITRIX 客户端会话,但我希望服务器上正在运行的 JVM 尽快释放内存(我的应用程序中只有很少的高消耗内存函数)。
If this behaviour cannot be controlled, can I let it like this and increase instead the OS virtual memory and let the OS using it as it wants without big performance issues. For example, would there be issues to have 10 java process of 1GB memory (with only 100MB real allocated objects in the heap) on a 4GB server with enough virtual memory of course.
如果无法控制这种行为,我是否可以让它像这样并增加操作系统虚拟内存并让操作系统根据需要使用它而不会出现大的性能问题。例如,在具有足够虚拟内存的 4GB 服务器上有 10 个 1GB 内存的 java 进程(堆中只有 100MB 实际分配的对象)会不会有问题。
I guess that other people already faced such questions/problems.
我想其他人已经面临过这样的问题/问题。
Thanks for your help.
谢谢你的帮助。
采纳答案by erickson
To control return of heap to the OS, from Java 5 onward, use the -XX:MaxHeapFreeRatiooption, as described in the tuning guide.
要控制堆返回操作系统,从 Java 5 开始,请使用该-XX:MaxHeapFreeRatio选项,如调优指南中所述。
If you feel your question is meaningfully different from this one, please point out how.
如果你觉得你的问题与这个问题有很大不同,请指出如何。
回答by Kai
First of all, System.gc() might as well do nothing. You really can't rely on it to do a garbage collection the way you are suggesting.
首先, System.gc() 也可以什么都不做。您真的不能依靠它来按照您建议的方式进行垃圾收集。
Second, you'll want to monitor what is actually going on the with GC by using
其次,您需要使用 GC 来监视实际发生的情况
-verbosegc -XX:+PrintGCDetails
in your invocation of java. Or by using JConsole, which it sounds like you're doing. But that System.gc() has me scared that you're counting the wrong thing...
在您调用 java. 或者通过使用 JConsole,听起来您正在这样做。但是 System.gc() 让我害怕你计算错了......
I suspect that when you say that the second or third garbage collection is when it frees the memory, you're just miscounting the garbage collections. A request to GC is not a GC! So check the logs (interpret them this way) that PrintGCDetails prints out.
我怀疑当您说第二次或第三次垃圾回收是释放内存时,您只是错误地计算了垃圾回收。对 GC 的请求不是 GC!因此,请检查PrintGCDetails 打印出的日志(以这种方式解释它们)。
In fact my problem is that I need to run several CITRIX clients sessions on a server, but I would like the running JVMs on the server to free the memory as soon as possible (I have only few high consuming memory functions in my application).
实际上,我的问题是我需要在服务器上运行多个 CITRIX 客户端会话,但我希望服务器上正在运行的 JVM 尽快释放内存(我的应用程序中只有很少的高消耗内存函数)。
While your problem is valid, the solution you're going for is a little shady. The JVM needs a heap size for exactly this reason - so that it can be guaranteed this space to run in. It seems like you're leaning towards launching an app, then waiting for the JVM to size its heap down, then launching another such that you're overbooking the resources on the machine. Don't do that, because it will all blow up once an app is taking more memory than you figured it would, but which it is entitled to.
虽然您的问题是有效的,但您要寻求的解决方案有点可疑。正是出于这个原因,JVM 需要一个堆大小 - 以便可以保证在这个空间中运行。似乎您倾向于启动一个应用程序,然后等待 JVM 缩小其堆的大小,然后启动另一个这样的您超额预订了机器上的资源。不要这样做,因为一旦应用程序占用的内存超出您的预期,它就会全部爆炸,但它有权获得。
I fully believe that you don't want to be micro managing Java's heap this way.
我完全相信您不希望以这种方式微管理 Java 的堆。
Read enough of http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.htmlto understand the generations and what the trade offs of a larger/smaller heap are.
阅读足够多的http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html以了解世代以及更大/更小堆的权衡是什么。
回答by nobody
I wouldn't worry about it until you see measurable slowdowns. If a process has memory allocated that it isn't using, the OS will swap the unused chunks to disk as needed.
在您看到可衡量的放缓之前,我不会担心。如果进程分配了未使用的内存,操作系统将根据需要将未使用的块交换到磁盘。

