无论是YGC仍是Full GC,GC过程当中都会对致使程序运行中中断,正确的选择不一样的GC策略,调整JVM、GC的参数,能够极大的减小因为GC工做,而致使的程序运行中断方面的问题,进而适当的提升Java程序的工做效率。可是调整GC是以个极为复杂的过程,因为各个程序具有不一样的特色,如:web和GUI程序就有很大区别(Web能够适当的停顿,但GUI停顿是客户没法接受的),并且因为跑在各个机器上的配置不一样(主要cup个数,内存不一样),因此使用的GC种类也会不一样(如何选择见GC种类及如何选择)。本文将注重介绍JVM、GC的一些重要参数的设置来提升系统的性能。html
JVM内存组成及GC相关内容请见以前的文章:JVM内存组成 GC策略&内存申请。java
JVM参数的含义 实例见实例分析web
参数名称 | 含义 | 默认值 | |
-Xms | 初始堆大小 | 物理内存的1/64(<1GB) | 默认(MinHeapFreeRatio参数能够调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制. |
-Xmx | 最大堆大小 | 物理内存的1/4(<1GB) | 默认(MaxHeapFreeRatio参数能够调整)空余堆内存大于70%时,JVM会减小堆直到 -Xms的最小限制 |
-Xmn | 年轻代大小(1.4or lator) | 注意: 整个堆大小=年轻代大小 + 年老代大小 增大年轻代后,将会减少年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8 |
|
-XX:NewSize | 设置年轻代大小(for 1.3/1.4) | ||
-XX:MaxNewSize | 年轻代最大值(for 1.3/1.4) | ||
-XX:PermSize | 设置持久代(perm gen)初始值 | 物理内存的1/64 | |
-XX:MaxPermSize | 设置持久代最大值 | 物理内存的1/4 | |
-Xss | 每一个线程的堆栈大小 | JDK5.0之后每一个线程堆栈大小为1M,之前每一个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减少这个值能生成更多的线程.可是操做系统对一个进程内的线程数仍是有限制的,不能无限生成,经验值在3000~5000左右 通常小的应用, 若是栈不是很深, 应该是128k够用的 大的应用建议使用256k。这个选项对性能影响比较大,须要严格的测试。(校长) 和threadstacksize选项解释很相似,官方文档彷佛没有解释,在论坛中有这样一句话:"” -Xss is translated in a VM flag named ThreadStackSize” 通常设置这个值就能够了。 |
|
-XX:ThreadStackSize | Thread Stack Size | (0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.] | |
-XX:NewRatio | 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代) | -XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5 Xms=Xmx而且设置了Xmn的状况下,该参数不须要进行设置。 |
|
-XX:SurvivorRatio | Eden区与Survivor区的大小比值 | 设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10 | |
-XX:LargePageSizeInBytes | 内存页的大小不可设置过大, 会影响Perm的大小 | =128m | |
-XX:+UseFastAccessorMethods | 原始类型的快速优化 | ||
-XX:+DisableExplicitGC | 关闭System.gc() | 这个参数须要严格的测试 | |
-XX:MaxTenuringThreshold | 垃圾最大年龄 | 若是设置为0的话,则年轻代对象不通过Survivor区,直接进入年老代. 对于年老代比较多的应用,能够提升效率.若是将此值设置为一个较大值,则年轻代对象会在Survivor区进行屡次复制,这样能够增长对象再年轻代的存活 时间,增长在年轻代即被回收的几率 该参数只有在串行GC时才有效. |
|
-XX:+AggressiveOpts | 加快编译 | ||
-XX:+UseBiasedLocking | 锁机制的性能改善 | ||
-Xnoclassgc | 禁用垃圾回收 | ||
-XX:SoftRefLRUPolicyMSPerMB | 每兆堆空闲空间中SoftReference的存活时间 | 1s | softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap |
-XX:PretenureSizeThreshold | 对象超过多大是直接在旧生代分配 | 0 | 单位字节 新生代采用Parallel Scavenge GC时无效 另外一种直接在旧生代分配的状况是大的数组对象,且数组中无外部引用对象. |
-XX:TLABWasteTargetPercent | TLAB占eden区的百分比 | 1% | |
-XX:+CollectGen0First | FullGC时是否先YGC | false |
GC性能方面的考虑算法
对于GC的性能主要有2个方面的指标:吞吐量throughput(工做时间不算gc的时间占总的时间比)和暂停pause(gc发生时app对外显示的没法响应)。spring
1. Total Heap数组
默认状况下,vm会增长/减小heap大小以维持free space在整个vm中占的比例,这个比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。缓存
通常而言,server端的app会有如下规则:并发
2. The Young Generationapp
另一个对于app流畅性运行影响的因素是young generation的大小。young generation越大,minor collection越少;可是在固定heap size状况下,更大的young generation就意味着小的tenured generation,就意味着更多的major collection(major collection会引起minor collection)。框架
NewRatio反映的是young和tenured generation的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限,将这两个值设为同样就固定了young generation的大小(同Xms和Xmx设为同样)。
若是但愿,SurvivorRatio也能够优化survivor的大小,不过这对于性能的影响不是很大。SurvivorRatio是eden和survior大小比例。
通常而言,server端的app会有如下规则:
经验&&规则
java.lang.StackOverflowError:(不多)
java.lang.OutOfMemoryError:heap space(比较常见)
java.lang.OutOfMemoryError: PermGen space (常常出现)
java.lang.OutOfMemoryError: PermGen space 这个异常比较常见,是说JVM里的Perm内存区的异常溢出,因为JVM在默认的状况下,Perm默认为64M,而不少程序须要大量的Perm区内存,尤为使用到像spring等框架的时候,因为须要使用到动态生成类,而这些类不能被GC自动释放,因此致使OutOfMemoryError: PermGen space异常。解决方法很简单,增大JVM的 -XX:MaxPermSize 启动参数,就能够解决这个问题
java.lang.OutOfMemoryError:heap space或 其它OutOfMemoryError,这个异常实际上跟上面的异常是一个异常,但解决方法不一样,因此分开来写。上面那个异常是由于JVM的perm区内存区分少了引发的(JVM的内存区分为 young,old,perm三种)。而这个异常是由于JVM堆内存或者说整体分少了。解决方法是更改 -Xms -Xmx 启动参数,一般是扩大1倍。xms是管理启动时最小内存量的,xmx是管里JVM最大的内存量的
在单线程操做中,不管是栈深度无限增长,仍是栈帧(每一个方法调用执行时都会在栈中建立一个栈帧,用来存储局部变量,操做数栈,动态链表,方法出口等信息)占的空间太大,都出现的是StackOverflowError