面试官问你GC怎么调优?思路是什么呀?我直接把这篇文章甩到面试官脸上
Posted Rolland_hero
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试官问你GC怎么调优?思路是什么呀?我直接把这篇文章甩到面试官脸上相关的知识,希望对你有一定的参考价值。
有学过JVM垃圾回收机制的小伙伴肯定了解过CG调优,当面试官问到这个问题时,相信很多小伙伴第一时间想到的就是调节几个参数,调节一下分代的大小。简单的可以用这么一句话概括,水多了加面,面多了加水。十分形象了。可是这么简单的几句话怎么能让面试官觉得你可以修航母呢?接下来,这篇文章就以修航母的角度来好好教教你怎么回答这个问题,让面试官耳目一新!
思路清晰,回答不虚。
这里先放一张思维导图来介绍一下回答GC调优的思路。
通过这张图我们可以梳理一下思路,首先GC调优可以从垃圾收集器的选择开始,根据业务环境选择不同的垃圾收集器,比如一个业务对低延迟的需求比较高,那么我们就可以选择以低延迟为目的的一些垃圾收集器比如:CMS和G1。又或者实际业务对吞吐量有着比较高的需求,那么我们就可以选择Parallel Scavenge收集器。所以第一步就是选择合适的垃圾收集器。
选完合适的垃圾收集器,现在就要对垃圾回收进行具体的调优了,正所谓最快的垃圾回收是不回收垃圾,那么对于垃圾产生那么多,我们首先需要考虑自己的代码是不是有问题,是不是编码问题造成了许多的数据冗余?是不是那个sql语句选出的数据太冗余了?考虑这个场景是不是可以使用软引用来降低内存占用呢?这就是垃圾回收调优的第二步,不发生GC就是最好的GC。
说完第二步,检查完代码确实没有什么问题,但是就是容易发生GC怎么办呢?好,我们接着往下讲。我们知道JVM的堆是分了几个代,一个是老年代,一个是新生代,新生代又分了Eden区和Servivor区,根据这个代不同的特性,我们的GC调优也会对应不同的策略。
第一个我们看新生代,新生代的特点是:所有的new操作分配内存都是非常廉价的、死亡对象回收零代价(新生代是标记复制算法)、大部分对象用过即死(朝生夕死)、MInor GC 所用时间远小于Full GC,所以根据这几个特点。我们就有相应的调优策略:调节新生代内存大小。那么怎么调呢? 一味地加大新生代地内存吗?还是一味地减少新生代内存呢?我们要知道加大新生代带内存会来什么后果,减少新生代内存会带来什么后果。加大新生代内存,我们可以获得更大的新生代内存,从而减少minor GC发生的次数,但是老年代内存占比有所降低,会更频繁地触发Full GC。而且触发Minor GC时,清理新生代所花费的时间会更长。那减少新生代内存会带来什么后果呢?频繁触发Minor GC,会STW,使得吞吐量下降。既然两者各有优劣,我们怎么才能平衡这个新生代的内存呢?JVM虚拟机HotSpot是这么建议的:新生代内存设置为内容纳[并发量*(请求-响应)]的数据为宜。
新生代里面又有幸存区,面对幸存区我们又要如何处理呢?我们知道,幸存区是来放GC之后存活的对象的,并且它有晋升机制,那么针对这个特性,我们调优的时候就要考虑,晋升阈值配置得当,让长时间存活的对象尽快晋升;稍微扩大幸存区,幸存区需要能够保存 当前活跃对象+需要晋升的对象;
说完新生代,我们剩下老年代了,对于老年代,我们知道,老年代是使用标记整理算法进行GC的,所以发生一次老年代的GC会比一次MinorGC用的时间多的多,那么我们首先想到的就应该是避免发生FullGC,避免发生FullGC的方法那就是,先去调优新生代,或者重复之前的调优方案,都试过了之后,还是容易发生FullGC那么我们就可以考虑增加老年代的内存来减少FullGC的次数了。
好了,总结一下思路就是这样:首先根据业务场景选择合适的回收器,顺带介绍一下垃圾回收器的特点。然后就是介绍各个分代的特点以及其对应的调优方法。
谢谢你读到这里!
以上是关于面试官问你GC怎么调优?思路是什么呀?我直接把这篇文章甩到面试官脸上的主要内容,如果未能解决你的问题,请参考以下文章
面试官问你JDK 13到底有哪些新特性?把这篇甩给他!完整详解
面试官问我什么是 Nginx正向代理反向代理,我把这篇甩给了他
面试官问你MyBatis SQL是如何执行的?把这篇文章甩给他