jvm垃圾回收相关优化笔记

来源:互联网 发布:中国菜刀源码 编辑:程序博客网 时间:2024/03/29 06:16

  首先是根据应用程序类型,如果是要求响应快,停顿小的应用,使用cms(老年代)。

   注重吞吐量的应用,可以使用paralle scanvage。  

   一般电商类型应用,使用cms作为老年代垃圾收集器,使用parNew作为新生代垃圾收集器。

   调优肯定是有基准的,一般由应用程序制定平均延迟响应时间,最坏延迟响应时间,平均延迟频率等。

   确定好后,先大体确定新生代与老年代大小,可以通过模拟应用线上环境,多次full gc后,得到[活跃数据大小]。将新生代大小设为1-1.5倍活跃数据大小。老年代一般为1.5至3倍。

  假设应用活跃数据大小为:300M,则可以将新生代大小设为450M,老年代为900M。相当于老年代大小为新生代大小2倍。

   实际2048M大小堆,默认年生代大小为:768M,老年代大小为:1280M。相当于1.6倍。

  有了最初的新生代与老年代大小时,接着开始先调新年代。不断模拟线上环境压请求,观察平均young gc的频度及gc时间,算出平均延迟gc时间。如果发现延迟要大于应用程序目标延迟时间,则适当减少eden,一般通过减少新生代,保持s0,s1大小不变。如果发现gc频率大于应用要求,则增加 eden。不断调整,如果还是不能满足应用要求,则采用分布式部署。

  老年代的调优,通常目标是防止出现类似担保失败而进行的stop-world full gc,这种gc是单线程,并且会停止所有应用,出现的条件是老年代空间用光了。

    当新生代在minor gc后还有很多存活对象 survior空间放不下时,会将这部分对象放入老年代,但老年代空间不够时就会发生担保失败,然后出现上面说的:stop-world full gc。

   在老年代碎片过多时,一个对象提供到老年代发现没有完整一块空间放得下这个对象,也会发生stop-world full gc担保失败。

   总结起来老年代担保失败进而stop-world full gc的原因,一个是老年代内存碎片,一个是由于新生代对象提供到老年代太快,老年代清理速度小于提升速度,这时也会发生担保失败。

  内存碎片问题及对象提升到老年代过快,可以通过减少年轻代对象提升到老年代的对象数量。这个可以通过增大年轻代大小,以及调整survior空间大小(注:survior空间大小时,y gc后,单个survior无法存放存活对象就会将对象提升到老年代)。这里需要注意的是:当所有新生代对象存活对象大于s0或s1的50%时,jvm会调整晋升限值。如果发现担保失败很多,可以排查下是不是survior空间太小,导致晋升年龄限值很低最终使得很多年轻对象都进入老年代。

  对于cms来讲,还可以设置老年代在达到老年代空间多少比例时,开始full gc。这个参数如果设太大,则容易出现担保失败。设太小又会过于频繁的full gc。

  分布式布署jvm应用,是个好选择。

  


  

0 0
原创粉丝点击