为什么 Java VM 进程消耗的 RAM 比 -Xmx 参数指定的要多?

为什么 Java VM 进程消耗的 RAM 比 -Xmx 参数指定的要多?

我有多台运行 CentOS 5.4 的服务器,但只有一个应用程序在 Java VM 上运行。我已使用以下参数配置了 Java VM:

java -Xmx4500M -server -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:NewSize=1024m  -Djava.net.preferIPv4Stack=true -Dcom.sun.management.jmxremote=true

我运行虚拟机的机器有 6 GB RAM,没有运行其他应用程序。过了一会儿,java 进程开始严重占用交换空间,我从命令中得到以下信息top

7658 root      25   0 11.7g 3.9g 4796 S 39.4 67.3 543:54.17 java

另一方面,如果我通过 JConsole 连接,它会报告 Java VM 已使用 2.6 GB、已提交 4.6 GB 并且最大为 4.6 GB。

java -version 返回:

java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)

为什么 Java VM 会扩展得远远超过其分配的堆大小?如果 JConsole 中没有报告,那么这些内存会去哪里?

答案1

我注意到一些基于 Java 的商业应用程序存在一个错误,这些应用程序在 32 位 Java 中运行良好,但在 64 位 Java 中启动时需要额外的(且大部分是不必要的)1.25GB。因此,在 32 位 Java 中需要 256MB 的东西在 64 位运行时需要 1.5GB。

我怀疑 Java 正在报告它认为应用程序正在使用的内容,但不是它自己的运行时开销,特别是在调用此错误的情况下。

您可以尝试在 32 位运行时上运行该应用程序,或者返回供应商的技术支持(可能要花费 $$)并询问发生了什么。

最终,如果您成功限制了总内存占用,那么您只会迫使应用程序更快地崩溃,而问题仍然会存在。

答案2

-Xmx 是虚拟机使用的最大堆空间量。它不包括加载的类的内存、虚拟机本身或线程堆栈或用于 JIT 的内存。顶部的行也具有误导性,因为第一个数字包括其他程序使用的共享内存。第二个数字 3.9g 是常驻大小,更接近实际情况。

我的建议:检查您是否真的需要那么多堆(对象的数量和大小)并尽可能减少 -Xmx 的数量。

相关内容