我在 Solaris 上使用 -Xmx256M 开关运行 Java 应用程序。当我通过 JMX 连接时,JVM 告诉我该应用程序正在使用大约 50Mb 的堆,并正确指出最大堆大小约为 250Mb。
然而,Solaris 却告诉我一个完全不同的故事。例如,当运行 pmap 时,我得到:
~ > pmap -S 10124 | grep heap
0002C000 3920 3920 rwx-- [ heap ]
00400000 815104 815104 rwx-- [ heap ]
显示令人难以置信的是,有 800Mb 的内存被用于堆空间。
ps 确认内存使用情况:
ps -eo vsz,rss,pid,args | sort -n
939368 925576 10124 /apps/../java -Xmx256M xxxx
我读了https://plumbr.eu/blog/why-does-my-java-process-consume-more-memory-than-xmx但是文章描述了 JVM 使用除堆之外的内存(即堆栈、本机库和线程) - 但在我的例子中,JVM 实际上使用了更多堆比指定的。
我的Java版本是:
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04)
Java HotSpot(TM) Server VM (build 20.6-b01, mixed mode)
更令人费解的是,我在同一台机器上运行了其他 Java 应用程序,使用相同的 JVM 和相同的设置,它们运行得非常好。这个应用程序之所以“特别”,是因为它连接到外部第三方应用程序(RET LBN,如果有帮助的话)。它不运行任何 JNI 或本机代码 - 那么为什么第三方库不遵守 JVM 的启动参数?
我已经束手无策了——任何帮助或指点都将不胜感激。
答案1
Java 堆是保存 Java 对象的一块内存。
“pmap”显示操作系统进程堆。这是用于运行 Java 进程的内存。这包括所有 Java 代码,以及构成 Java 运行时环境的所有 C 代码。
要显示 Java 堆,请尝试 jconsole 的“内存”选项卡,或者 jmap 或 jstat。