JAVA全面了解GC调优

有必要优化GC吗?数组

确切的说是 基于Java的应用必定须要进行GC优化吗?我认为并不是全部基于Java的应用都须要进行GC优化,例如基于Java的系统有以下参数或行为:性能

  • 已经经过-Xms 和 -Xmx 指定了内存大小
  • 包含了 -server 参数
  • 系统中未出现 超时 等日志

换句话说,若是你没有设置内存大小并且出现了大量超时日志,那么你须要在系统中进行GC优化了。 优化

可是有件事要铭记于心:GC优化是你最后的手段。ui

思考下GC优化的根本缘由:Java中建立的对象由垃圾收集器来清理,同时待清理对象的数量和各种GC的执行次数又和建立对象总数量成正比。所以,为了控制GC的执行,首先要作的是 减小建立对象的总数量spa

俗话说,”聚沙成塔”。咱们须要关注一些小事情,不然”养成气候”以后将难以驾驭。例如:日志

  • 使用StringBuilder或StringBuffer代替String
  • 尽量少的输出日志

若是在几回参数调整后内存使用状况有所改善,你就能够进行GC优化了。我将GC优化的目的分红两类:server

  • 将转移到老年代的对象数量降到最少
  • 减小Full GC的执行时间(减小stop the word发生次数)

 

将转移到老年代的对象数量降到最少

Oracle JVM提供了分代垃圾回收机制(JDK1.7及以上的G1 GC除外)。换句话说,对象建立在Eden区,而后在Survivor的From和To区之间移动,最后存活的对象被转移到老年代。一些大对象在Eden区建立以后被直接转移到老年代。相对新生代,老年代的GC消耗的时间更长。所以,减小重新生代转移到老年代的对象数量能够下降Full GC的频率。对象

 减小重新生代转移到老年代对象的数量的说法容易形成误解,并且也不可能,但能够经过 调全年轻代的大小 来实现。生命周期

减小Full GC的时间

和Minor GC相比,Full GC的执行时间长不少。所以,若是执行Full GC的时间过长(超过1s),将致使链接服务的请求超时。事件

若是经过减小老年代的大小来下降Full GC执行时间,会形成OutOfMemoryError或增长Full GC的次数

若是老年代设置太小,就会频繁触发full gc,full gc是很是耗时的。年轻代在通过n(hotspot默认是15)轮后会进入老年代,这样老年代顶不住了,就会触发full gc,回收时须要stop the world,这样系统常常发生长时间停顿,影响系统的吞吐量。

若是增大老年代大小以期减小Full GC的执行次数,那么执行时间又会增长

所以,须要合理的设置 老年代大小。

stop-the-world事件耗时很长

不合适的GC选项可能致使stop-the-world时间过长,你能够经过分析器或heap dump来定位问题。

这意味着你能够在检查堆中对象类型和数量后判断缘由。若是你发现不少没必要要的对象,你最好修改源码,若是建立对象过程当中没有什么特别的问题,最好直接变动GC参数。

影响GC性能的参数

不要去想 “有人在使用一些GC参数后性能显著提高,为何咱们不使用相同的参数?“,缘由是 不一样Web应用中对象的大小和生命周期不一样。

对于Java GC参数的设置,设置多个参数并不会提升GC的执行速度,偏偏相反,可能会下降执行速度。GC优化的基本原则是:将不一样的GC参数应用到2个或多个主机,而后比对结果,最后将性能最优的参数组合推广到其余主机,这点必须铭记于心。

下表是一些影响GC性能的参数。

表1: GC优化时须要检查的JVM参数

分类 参数 描述

堆区  -Xms 启动JVM时的初始堆大小

         -Xmx 最大堆内存

新生代  -XX:NewRatio 新生代和老年代内存大小比例

             -XX:NewSize 新生代大小

             -XX:SurvivorRatio Eden和Survivor区的比率

 

我常用 -Xms、-Xmx、-XX:NewRatio 三个参数来进行GC调优。-Xms、-Xmx 是确定须要的,-XX:NewRatio 的设置将会显著的影响GC性能。

有的人可能会问 如何设置Perm区大小? 你能够经过 -XX:PermSize、-XX:MaxPermSize 设置,这个会与Perm区 OutOfMemoryError相关。

另外一个会影响GC性能的是 GC类型,下面是基于JDK1.6可选的GC类型:

类别   参数   备注

Serial GC                         -XX:+UseSerialGC

Parallel GC                      -XX:+UseParallelGC

                                        -XX:ParallelGCThreads=value

Parallel Compacting GC  -XX:+UseParallelOldGC

CMS GC                          -XX:+UseConcMarkSweepGC

                                        -XX:+UseParNewGC

                                        -XX:+CMSParallelRemarkEnabled

                                        -XX:CMSInitiatingOccupancyFraction=value

                                        -XX:+UseCMSInitiatingOccupancyOnly

G1                                   -XX:+UnlockExperimentalVMOptions

                                        -XX:+UseG1GC 在JDK6,这两个参数必须同时使用

除G1 GC外,GC类型能够经过第一行的参数来切换。最多见的GC类型是 Servial GC,它针对客户端系统专门进行了优化。

影响GC性能的参数有不少,可是上面的参数有着最为显著的影响。记住,设置过多的参数并不能保证必定会缩短GC的时间。

参考:https://chenyongjun.vip/articles/56

相关文章
相关标签/搜索