我们都使用过 java -jar xxx.jar包去运行jar包。但是有时候要指定jar包运行时内存,该怎么做,而且设置多大怎么衡量,很多人从来没有了解过。
背景:
我们开发java程序,可能涉及到开发环境,测试环境,生产环境。然后每个环境的服务器配置可能是不一样的。比如说开发环境可能是8G的内存 测试环境是 16G的内存,生产环境是 32G的内存。那么我们运行jar的指定内存应该是不一样的,否则就造成了硬件资源的浪费。
例如:java -jar -Xms1024m -Xmx1536m -XX:PermSize=128M -XX:MaxPermSize=256M XXX.jar
java -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M MyClass
各参数含义:
-Xms128m JVM初始分配的堆内存
-Xmx512m JVM最大允许分配的堆内存,按需分配
-XX:PermSize=64M JVM初始分配的非堆内存
-XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配
先了解一下虚拟机内存模型:
堆内存分配
JVM初始分配的堆内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的堆内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;
空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx 相等以避免在每次GC 后调整堆的大小。
说明:如果-Xmx 不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM,不是Throwable的,无法用try...catch捕捉。
非堆内存分配
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。(还有一说:MaxPermSize缺省值和-server -client选项相关,
-server选项下默认MaxPermSize为64m,-client选项下默认MaxPermSize为32m。这个我没有实验。)
上面错误信息中的PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。还没有弄明白PermGen space是属于非堆内存,还是就是非堆内存,但至少是属于了。
XX:MaxPermSize设置过小会导致java.lang.OutOfMemoryError: PermGen space 就是内存益出。