我正在运行最大堆大小为 128 MB (-Xmx128M) 的 Java 应用程序。它正在成功运行,没有 OutOfMemoryError 或任何其他未处理的异常。因此,我假设它的实际堆大小确实保持在声明的 128 MB 限制范围内。
但是,在观察此 Java 应用程序的进程时,我发现总内存使用量的峰值为 4,188,548 KB(~4 GB)。这是堆的受控最大大小的 30 多倍的增长。虽然我知道这个值包括分配的虚拟内存,它可能比实际使用的物理内存大得多,但它会影响硬限制,例如 Sun Grid Engine 强加的限制,因此它是有意义的。
这到底是怎么可能的?我知道 JVM 消耗的总内存比堆的大小要多得多,但我不明白它为什么需要比应用程序实际需要的几 GB 的额外内存来创建其对象并执行其计算.
我在 64 位 RHEL Linux 发行版上使用 Sun Java 1.6.0.31。
最佳答案
除了由 -Xmx
控制的 Java 堆外,还有几个内存接收器:
- 线程堆栈
- 永久代空间
- 直接
ByteBuffers
和映射ByteBuffer
- 本地代码/库分配的内存
在不知道您系统的详细信息的情况下,我猜想,某些东西使用了映射的 ByteBuffers
。
但是您可以通过检查 pmap
命令的输出来深入了解这个问题。它列出了进程的所有内存区域以及任何区域映射到的文件名(当然,如果区域是映射的话)。
关于java - 为什么我的 JVM 的总内存使用量比它的 Xmx 值大 30 多倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9725633/