我的 jre 如何超出其堆限制?

我的 jre 如何超出其堆限制?

我有一个 jvm,它的实际内存使用量远远超出了启动时的限制。它是一台 Sun VM:

root@jira:/opt/atlassian/jira/jre# ./bin/java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)

并且它已配置了最大堆 768MB ( -Xmx768m) 和最大永久代 256MB ( -XX:MaxPermSize=256m),但进程已远远超过 1GB,目前为 1.7GB。

我习惯于当存在内存泄漏的 Java 应用程序超出其限制时,通过 OutOfMemoryErrors 自行终止,而不是在 Linux OOMKiller 开始射击进程时被外部终止。

ps

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
jira     23030  2.7 70.5 2181356 1457748 ?     Sl   Nov30  34:52 /opt/atlassian/jira/jre//bin/java -Djava.util.logging.config.file=/opt/atlassian/jira/conf/logging.properties -XX:MaxPermSize=256m -Xms256m -Xmx768m

有 1.5GB 并且它会持续增长直到 2GB 的盒子开始交换。

我对 JVM 内存限制有什么误解?

答案1

堆限制是提供给 Java 应用程序的 JVM 堆的限制(没有 Java 程序可以在堆上分配超过该量的空间),但不限制 Java 进程的大小(包括您限制的 JVM 堆,加上 JVM 本身分配的任何项目,加上堆栈(用于 JVM 和您的 Java 应用程序),加上我几乎肯定会遗漏的其他东西。

通常情况下,您不会看到超出设定限制的膨胀超过 10-15%,但可能存在病态情况,甚至可能存在内存泄漏或 Java 运行时本身的其他错误(祝你好运调试那头猪)。

如果你想在操作系统级别限制 Java 运行时的大小,你应该考虑ulimit命令。JVM 可以妥善处理达到这些限制的情况。

答案2

这里有堆外区域,其中包括 JNI 代码和 Direct Byte 缓冲区分配的内存。您可以使用 来控制后者-XX:MaxDirectMemorySize

相关内容