JVM进程大小和内存堆大小之间的巨大差异

我在Windows 8.1 64bit上使用4GB RAM开发java swing应用程序 JDK version 8u20 64bit.

问题是当我使用带有Monitor选项的 Netbeans profiler 启动应用程序时 .

加载第一个Jframe时,应用程序内存堆大约为 18mb ,JVM进程大小大约为 50mb (image1) .

然后,当我启动包含带有webView的JFxPanel的其他Jframe时,Heap跳转到 45mb 并且JVM进程跳转到 700mb very fast (image2) ,这非常令人困惑 . 然后当我关闭第二个JFrame并且它被释放并且调用System.gc()并且JVM执行GC(在大多数情况下)时,堆落到 20mb 左右但JVM进程从不丢弃 (image3) .

为什么内存堆(45 Mb)和JVM进程(699 Mb)之间存在巨大差异?为什么JVM需要所有内存?以及如何减少这个数额?我正在使用这些vm选项启动应用程序:

-Xms10m  -Xmx60m -Xss192k
-XX:+UseG1GC -XX:MinHeapFreeRatio=5
-XX:MaxHeapFreeRatio=10  -XX:PermSize=20m
-XX:MaxPermSize=32m

EDIT :- 我刚刚阅读了该链接JVM memory usage out of control中的问题并且他遇到了同样的问题,但情况不同他的堆大小是JVM进程内存总大小的33%,在我的情况下小于7%并且他正在做多个工作同时(Tomcat webapp),我不会用我所做的相同VM参数启动他的应用程序 .

UPDATE :- 在第一个JFrame启动后(image1)

First JFrame launched

第二个JFrame启动后(image2)

Second JFrame launch

第二个JFrame关闭后(image3)

Second JFrame closed

EDIT 2 :- 我刚刚使用上面相同的VM参数尝试了相同的应用程序并添加了

-client 
-XX:+UseCompressedOops

并使用 JDK 8u25 32-bit 因为正如本答案_367017中所述,64位版本不包含JRE中的客户端文件夹,并将忽略-client参数 .

结果是当第二个JFrame打开并且堆大小(在三个点中)与64位版本中的数量几乎相同时,总内存进程跳转到 540Mb ,这是否确认这是一个与问题相关的问题到JVM(相同的堆大小和总进程大小的 260Mb 差异)?

回答(1)

3 years ago

虚拟内存分配大多不相关(参见解释this answer),与实际内存使用情况大不相同 . JVM不是为限制虚拟内存分配而设计的,请参阅有关limiting virtual memory usage的问题 .
最终用户可能会在任务管理器中看到大量虚拟内存使用情况,但这几乎毫无意义 . Windows任务管理器中显示的内存使用的不同数字在this article中进行了解释 . 总结:在Windows任务管理器中查看"Memory (Private Working Set)"和"Page Fault Delta"(后者的相关性在this answer中解释) .