JVM在执行Java程序时会把它所管理的内存划分为若干个不同的运行时数据区域,主要包括:程序计数器、方法区、虚拟机栈、本地方法栈和堆:
针对堆空间的优化是Java性能调优的重点之一。如果没有设置JVM堆空间大小,JVM会根据服务器物理内存大小设置默认堆大小的值。例如,在64位的服务器端,当物理内存小于192MB时,JVM堆大小默认选为物理内存的一半;当物理内存大192MB且小于128GB时,JVM堆大小默认选为物理内存的四分之一;当物理内存大于等于128GB时,都为32GB。通常情况下,Java应用程序的会通过参数指定堆大小,具体方法下文会有说明。
应用程序选用多大的堆空间大小及配比,一般要根据程序的GC情况和服务器内存资源进行综合评估,是个循序渐进不断优化的过程,如果垃圾回收(GC)频繁触发,可以尝试增加堆空间缓解。
推荐配置原则:
在Java应用程序启动时,添加如下参数并设置大小:
参数 |
说明 |
---|---|
-Xmx |
设置JVM最大可用堆内存大小。 |
-Xms |
设置初始堆大小,一般和Xmx保持一致。 |
-Xmn |
设置年轻代堆大小。 |
-Xss |
设置每个线程的堆大小。JDK 1.5以后每个线程堆栈大小默认为1MB,1.5以前为256K。 |
-XX:NewRatio= |
设置年轻代(包括Eden和两个Survivor区)与老年代的比值(不包括永久代)。如设置为4,则年轻代与老年代所占比值为1:4,年轻代占整个堆栈的1/5。 |
-XX:SurvivorRatio= |
设置年轻代中Eden区与Survivor区的大小比值。如设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6。 |
-XX:MaxPermSize= |
设置永久代堆大小。 |
举例:
java -Xmx3600m -Xms3600m -Xmn2g -Xss128k
设置最大堆空间为3600MB,初始化堆大小为3600MB,年轻代大小为2GB,线程堆大小为128KB。