5.JVM调优
- 在代大小的调优上,最关键的参数为:-Xms、-Xmx、-Xmn、-XX:SurvivorRatio、-XX:MaxTenuringThreshold
- 避免新生代大小设置过小:当新生代大小设置过小时,会导致minor GC的次数更加频繁且有可能导致minor GC的对象直接进入老年代,此时如进入老年代的对象占据了剩余空间,将触发Full GC。
除了调大新生代大小外,如果能够调大堆的大小,那就更好,但堆调大意味着单次GC时间的增加。
当minor GC过于频繁,或发现经常出现minor GC时,Survivor的一个区域空间满且老年代增长超过了Survivor区域大小时,就需要考虑调整新生代的大小了。调整时的原则是在不能调大堆的情况下,尽可能放大新生代空间,尽量让对象在minor GC阶段被回收。但新生代空间也不可过大,在能够调大堆的情况下,则可以按照增加的新生代空间大小增加堆大小,保证老年代空间够用。 - 避免新生代设置过大: 会导致老年代变小了,有可能导致Full GC频繁执行;minor GC的耗时大幅度增加。
大多数场景下都应设置得比老年代小,推荐是堆的33%。 - 避免Survivor区过小或过大:调大SurvivorRatio意味着Eden区变大,minor GC的触发次数会降低,但此时Survivor区域的空间变小了,如有超过Survivor空间大小的对象在minor GC后仍没有被回收,则会直接进入旧生代。调小则意味着Eden区变小,minor的触发次数会增加,但Survivor区可以储存更多minor GC后仍存活的对象,避免其进入老年代。
- 合理设置新生代存活周期
GC策略调优 - 大部分Web应用在处理请求时设置了一个最大可同时处理的请求数,当超过此请求数时,会将之后的请求放入等待队列中,而这个等待队列也限制了大小。当满了后仍有请求进入,那么这些请求将会被直接丢弃,所有的请求又都是有超时限制的。 因此Web应用非常需要一个暂停时间短的GC,再加上大部分Web应用的瓶颈都不在cpu上,所以CMS是个不错的选择。
- 在进行参数调整时,可根据目前收集到的顶峰时系统请求次数、响应时间以及G提升C的信息,来估计系统每次请求需要消耗的内存,以及每次minor GC时存活的对象所占的内存,从而估计需要设置多大的Survivor才能够尽可能地避免对象进入老年代
- 由于参数的估计是以请求次数和响应时间为基准的,因此一旦系统的响应速度下降或请求的次数上升,就可能仍然会导致大量对象进入老年代,从而触发频繁的Full GC,频繁的Full GC又导致系统的响应速度下降,从这个层面看,根本需要做的调优仍然是提升请求的处理速度以及降低每次请求需要分配的内存,只有这样才能使得应用能够支撑更高的并发量。
- 目前内存管理方面,JVM自身已经做得非常不错了,如果如果不是有确切的GC造成性能低的理由,就没必要做过多细节方面的调优。多数情况下只需要选择GC策略并设置堆的大小即可。