我正在开发一款Java Swing应用程序,运行环境是Windows 8.1 64位,内存为4GB,JDK版本为8u20 64位。
问题是当我使用Netbeans profiler的Monitor选项启动应用程序时,出现了以下情况:
当第一个Jframe被加载时,应用程序的内存堆大约为18MB,JVM进程大小约为50MB(image1)。
然后,当我启动包含JFxPanel和webView的其他Jframe时,堆跳到了45MB,而JVM进程迅速跳到了700MB(image2),这非常令人困惑。 接着,当我关闭第二个JFrame并释放它时,会调用System.gc()进行GC(大多数情况下)。此时,堆会降至约20MB,但JVM进程的大小却不会下降(image3)。
为什么内存堆和JVM进程之间有如此巨大的差异(45 MB vs. 699 MB)? 为什么JVM需要那么多内存?如何减少它的使用量? 我使用以下VM选项启动应用程序:
-Xms10m -Xmx60m -Xss192k
-XX:+UseG1GC -XX:MinHeapFreeRatio=5
-XX:MaxHeapFreeRatio=10 -XX:PermSize=20m
-XX:MaxPermSize=32m
编辑:我刚才阅读了这个链接中的问题JVM memory usage out of control,他有同样的问题,但情况不同,他的堆大小约为总JVM进程内存大小的33%,而我的情况少于7%,他正在同时执行多个工作(Tomcat webapp),而我不是(Java Swing应用程序),他没有像我一样使用相同的VM参数启动应用程序。
更新: 第一个JFrame启动后(图片1)
第二个JFrame启动后(图片2)
第二个JFrame关闭后(图片3)
编辑2: 我刚刚尝试使用相同的VM参数运行相同的应用程序并添加了
-client
-XX:+UseCompressedOops
我使用了 JDK 8u25 32-bit,因为在这个答案中提到 https://dev59.com/Q3VC5IYBdhLWcg3wvT1a#15471505,64位版本没有包含JRE中的client文件夹并且会忽略-client参数。
结果是,当第二个JFrame打开时,进程的总内存跳到了540Mb,而堆大小(在三个点中)几乎与64位版本中的数字相同。这是否证实了这是一个与JVM有关的问题(相同的堆大小和总进程大小相差260Mb)?