[英]Why does this java process not release memory?
I have written a java application and I have run the java process under Fedora 24. Then I checked jconsole and found out that it uses around 5 to 10 megabytes of memory. 我编写了一个java应用程序,我在Fedora 24下运行了java进程。然后我检查了jconsole,发现它使用了大约5到10兆字节的内存。 The effect of garbage collection is also visible in the graph.
垃圾收集的效果在图中也可见。
Then I checked my System Monitor and found out that the same process ID has more than 100 megabytes memory usage. 然后我检查了我的系统监视器,发现相同的进程ID有超过100兆字节的内存使用量。
Here is the screenshot: 这是截图:
Please tell me why doesn't the process release unused memory? 请告诉我为什么这个过程没有释放未使用的内存?
Is there any way to release it? 有没有办法释放它?
There is a difference between used heap and allocated heap. 使用的堆和已分配的堆之间存在差异。 The blue line in your graph is the used heap - how much of the heap is actually holding objects.
图中的蓝线是用过的堆 - 实际持有对象的堆的数量。 What is not shown is the size of the heap which is allocated - this is larger, often much larger, so that the JVM can allocate more objects without running out of space and having to go back to the OS for more memory (which is expensive).
未显示的是分配的堆的大小 - 这个更大,通常要大得多,这样JVM可以分配更多的对象而不会耗尽空间并且必须返回操作系统以获得更多内存(这是昂贵的) )。 In your case, some of that 100mb which the system is showing is the JVM itself, but most of it is likely allocated but unused heap.
在您的情况下,系统显示的100mb中的一些是JVM本身,但其中大部分可能已分配但未使用的堆。
When you run a Java program without specifying the heap size you want it to use the JVM will try to figure out a sensible setting based on your machine, OS, JVM version etc. When I just ran a simple Hello World on my machine with 16GB of RAM and Java 8 it initially allocated 256mb for the heap. 当您运行Java程序而未指定您希望它使用的堆大小时,JVM将尝试根据您的计算机,操作系统,JVM版本等找出合理的设置。当我在16GB的机器上运行简单的Hello World时在RAM和Java 8中,它最初为堆分配了256mb。 Obviously much more than it needs!
显然远远超过它的需要! If I wanted to force it to use less I can use the
-Xms
command line to set the initial heap allocation and -Xmx
to set the maximum allowed. 如果我想强制它使用less,我可以使用
-Xms
命令行设置初始堆分配,使用-Xmx
设置允许的最大值。 My guess is that if you set something like -Xms20m
you'd see less memory being used by your process. 我的猜测是,如果你设置像
-Xms20m
类的-Xms20m
你会发现你的进程使用的内存更少。 In IntelliJ add that setting to the VM Options
field in your run configuration. 在IntelliJ中,将该设置添加到运行配置中的
VM Options
字段。
The memory reported in the System Monitor is all memory used by the process, not just Java heap. 系统监视器中报告的内存是进程使用的所有内存,而不仅仅是Java堆。 This memory includes the:
这个记忆包括:
In your case, 10MB of the process is being used to store the Java stack and the Java objects. 在您的情况下,正在使用10MB的进程来存储Java堆栈和Java对象。 The other 90MB is the Java program itself and the memory internal to the VM.
另一个90MB是Java程序本身和VM内部的内存。
That's the short answer, but there is one other important consideration - Java can (and does) free excess heap back to the OS. 这是简短的答案,但还有另一个重要的考虑因素 - Java可以(并且确实)将多余的堆释放回操作系统。 This is controlled by the
-XX:MinHeapFreeRatio
and -XX:MaxHeapFreeRatio
flags. 这由
-XX:MinHeapFreeRatio
和-XX:MaxHeapFreeRatio
标志控制。 By default the MaxHeapFreeRatio is 70% - which is almost exactly what is shown in your Heap graph (the saw tooth pattern from 6MB to a bit under 10MB). 默认情况下,MaxHeapFreeRatio是70% - 这几乎就是你的Heap图中显示的内容(锯齿图案从6MB到10MB以下)。 If your app had a significantly larger drop, you would see a (small) saw tooth pattern for the Java process in the System Monitor.
如果您的应用程序具有明显更大的下降,您将在系统监视器中看到Java进程的(小)锯齿模式。
For performance, you should generally allow the JVM to keep hold of a significant chunk of the heap freed from a GC. 为了提高性能,通常应该允许JVM保留从GC中释放的大量堆。 Why?
为什么? Because we know that the JVM will immediately need to start allocating memory again and it's more efficient for the process (and the OS) for Java to keep this.
因为我们知道JVM将立即需要再次开始分配内存,并且Java的进程(和操作系统)更有效地保持这一点。
So, in summary: 所以,总结一下:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.