jvm老年代调优

老年代调优

以 CMS 为例 :

  • CMS 的老年代内存越大越好
  • 先尝试不做调优,如果没有 Full GC 那么已经…,否则先尝试调优新生代
  • 观察发生 Full GC 时老年代内存占用,将老年代内存预设调大 1/4 ~ 1/3
    • -XX:CMSInitiatingOccupancyFraction=percent

接下来呢,我们来看一下老年代的一个调优。这里,我以CMS垃圾回收器为例来进行讲解。

第1条规则就是老年代的这个内存,也是设得越大越好。之前呢,我们也介绍过,CMS这个垃圾回收器,它是一种低响应时间的,并且是一个并发的一个垃圾回收器。也就是他的垃圾回收线程,在工作的同时,其他的用户现场也能够并发的执行。但是我们也讲过,就是这样有一个缺点,由于垃圾回收的同时其他的用户线程也在运行。所以就会产生新的垃圾,这些新的垃圾被称为浮动垃圾。那如果是这个浮动垃圾产生了,又导致你这个内存不足,这时候事儿就大了,就会造成你的这个CMS并发失败,并发失败了的话,你的CMS垃圾回收器就不能正常工作,它就会退化为serial old串行的老年代的垃圾回收器,这个效率就特别低了,一下子就会stop the world,导致你的这个响应时间变得特别长。所以我们在给这个老年代的规划内存的时候,就可能需要把它规划的更大一些,越大越好,这样呢就是为了预留更多的空间,避免浮动垃圾引起的并发失败。这是第1点。

第2点就是大家在做这个老年代调之前先要尝试一下,不要调优。为什么呢?如果你这个程序,正常运行了一段时间以后你并没有发现Full GC,即不是由于老年代的空间不足引起的垃圾回收,那说明我们的老年代这个空间很充裕,这种没有Full GC,说明你这个系统工作的已经是很OK了,所以先别尝试做老年代的调优。即使是发生了Full GC,你也应该先从调试新生代开始尝试,去调整新生代的大小,包括它的这个幸存区的大小(它的容量)、幸存区晋升阈值等这些手段都用了还是经常发生Full GC,你再回过头来看看老年代的这个设置。一旦老年代仍然发生Full GC,那么怎么办呢?你观察一下发生Full GC时,这个老年代是由于超过了多大的内存,导致了Full GC的发生,那你可以在这个原有发生Full GC时,这个内存的基础上给它调大,调大1/4—1/3。这样,就相当于我划分更合理的更大的一个内存给老年代使用,减少老年代的Full GC产生。

最后呢,还有一个相关参数,这个参数之前也介绍过,他是一个比例,是百分比。这个比例呢,就是控制了我老年代的空间占用达到老年代总内存的百分之多少的时候,使用CMS进行一个垃圾回收。这个值越低,老年代垃圾回收的触发时机就越早。我看过一个演讲,是一个推特的一个工程师,在他的这个演讲里甚至建议把这个值设置为零,设置为零,意思是什么呢?只要老年代有垃圾就会回收。不会等到他占满整个老年代内存的百分之多少以后才会进行回收。当然这是一个比较极端的值,也对你这个服务器的CPU有较高的要求,你必须有一个始终空闲CPU来做CMS的大型回收。因为他要并行的跟其他用户线程一起运行,所以也需要一个空闲的CPU来做这件事。但是,我个人感觉这是一种比较极端的做法,一般来讲呢,我们都会把这个比例设置为75%~80%之间。意思就是说预留20%~25%的空间给那些浮动垃圾。

这是以CMS为例介绍老年代的调优。

你可能感兴趣的:(jvm,jvm,java,算法)