我有一个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)
并且configuration了最大堆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内存限制有什么误解?
堆的限制是提供给Java应用程序的JVM堆的限制(没有Java程序可以在堆上分配的空间量),但不限制Java进程的大小(其中包括JVM堆,再加上堆栈(对于JVM和你的Java应用程序),再加上其他的东西,我几乎肯定会抛出。
通常情况下,你不会看到超过你设置的限制10-15%的膨胀,但病理情况可能存在,甚至可能是java运行时本身的内存泄漏或其他错误(祝你好运debugging猪)。
如果您想在操作系统级别限制Java运行时的大小,您应该查看ulimit命令。 JVM可以很好地处理这些限制。
有堆区,其中包括由JNI代码和直接字节缓冲区分配的内存。 您可以使用-XX:MaxDirectMemorySize控制最后一个。