GC在什么时候,对什么东西,做了什么事情

原文:

https://mp.weixin.qq.com/s?__biz=MzAxNDMwMTMwMw==&mid=2247489508&idx=1&sn=0485418697ff689e2964cc4ff30a7819&chksm=9b9436fcace3bfea8a69ac5312c5ee4bfd960c1080c53f26511d9c50d4b24f433d63a8bbf241&mpshare=1&scene=1&srcid=0930kFrXoVeK61g4GarEE9Te#rd --------------------- 作者:Ontheroad_ 来源:CSDN 原文:https://blog.csdn.net/Ontheroad_/article/details/82905165?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!

一个面试官对JVM面试问题的分析

 

问题:GC在什么时候,对什么东西,做了什么事情

 

什么时候:

1.系统空闲的时候

这种回答大约占30%,遇到的话一般我就会转向别的话题,譬如算法、SSH看看能否发掘一些他擅长的其他方面

2.系统自身决定,不可预测的时间/调用System.gc()的时候

这种回答大约占50%,大部分应届生都能回答到这个答案,起码不能算错误是吧,后续应当细分一下到底是语言表述导致答案太笼统,还是本身就只有这样一个模糊的认识。 

3.能说出新生代、老年代结构,能提出minor gc/full gc

分析:到了这个层次,基本上能说对GC运作有概念上的了解,譬如看过《深入JVM虚拟机》之类的。这部分不足10%。 

4.能说明minor gc/full gc的触发条件、OOM的触发条件,降低GC的调优的策略

分析:列举一些我期望的回答:eden满了minor gc,升到老年代的对象大于老年代剩余空间full gc,或者小于时被HandlerPromotionFailure参数强制full gc;gc与非gc时间消耗超过了gcTimeRatio的限制引发OOM,调优诸如通过NewRatio控制新生代老年代比例,通过MaxTenuringThreshold控制进入老年代生存次数等。。。能回答道这个阶段就会给我带来比较高的期望了,当然面试的时候正常人都不会记得每个参数的拼写,我自己写这段话的时候也是翻过手册的。回答道这部分的小于2%。 

 

对什么东西

1.不使用的对象。 

分析:相当于没有回答,问题就是在问什么对象才是“不使用的对象”。大约占30%。

2.超出作用域的对象/引用计数为空的对象。 

分析:这2个回答站了60%,相当高的比例,估计学校教java的时候老师就是这样教的。第一个回答没有解决我的疑问,gc到底怎么判断哪些对象在不在作用域的?至于引用计数来判断对象是否可收集的,我可以会补充一个下面这个例子让面试者分析一下obj1、obj2是否会被GC掉? 

 
  1. class C{

  2. public Object x;

  3. }

  4. C obj1、obj2 = new C();

  5. obj1.x = obj2;

  6. obj2.x = obj1;

  7. obj1、obj2 = null;

主流的java虚拟机里面没有选用引用计数法来管理内存,最主要的原因就是它很难解决对象之间相互循环引用的问题

3.从gc root开始搜索,搜索不到的对象

分析:根对象查找、标记已经算是不错了,小于5%的人可以回答到这步,估计是引用计数的方式太“深入民心”了。基本可以得到这个问题全部分数。 

PS:有面试者在这个问题会补充强引用、弱引用、软引用、幻影引用区别等,不是我想问的答案,但是可以加分

4.从root搜索不到,而且经过第一次标记、清理后,仍然没有复活的对象??

分析:我期待的答案。但是的确很少面试者会回答到这一点,所以在我心中回答道第3点我就给全部分数。 

即使在可达性分析算法中不可达对象,也是并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象的死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连的引用链,那么将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都是视为“没有必要执行”。

如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queued的队列之中,并在稍后由一个由虚拟机自动创建的、低优先级的Finalizer线程去执行它。这里所谓的“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是,如果一个对象在finalize()方法中执行缓慢,或者发生了死循环(更极端的情况),将很可能导致F-Queue队列中其他对象永久处于等待,甚至导致整个内存回收系统崩溃。finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象在finalize()方法中成功拯救自己---只要重新与引用链上的任何一个对象建立关系即可,那么第二次标记时它将被移除出“即将回收”的集合;如果对象这时候还没有逃脱,那基本上它就真的被回收了。

(《深入理解Java虚拟机》P66)

 

 

做了什么事情

最后由一个问题:“做什么事情”,这个问发挥的空间就太大了,不同年代、不同收集器的动作非常多。

1.删除不使用的对象,腾出内存空间。 

分析:同问题2第一点。40%。 

2.补充一些诸如停止其他线程执行、运行finalize等的说明。 

分析:起码把问题具体化了一些,如果像答案1那样我很难在回答中找到话题继续展开,大约占40%的人。 

补充一点题外话,面试时我最怕遇到的回答就是“这个问题我说不上来,但是遇到的时候我上网搜一下能做出来”。做程序开发确实不是去锻炼茴香豆的“茴”有几种写法,不死记硬背我同意,我不会纠语法、单词,但是多少你说个思路呀,要直接回答一个上网搜,我完全没办法从中获取可以评价应聘者的信息,也很难从回答中继续发掘话题展开讨论。建议大家尽量回答引向自己熟悉的,可讨论的领域,展现给面试官最擅长的一面。 

3.能说出诸如新生代做的是复制清理、from survivor、to survivor是干啥用的、老年代做的是标记清理、标记清理后碎片要不要整理、复制清理和标记清理有什么优劣势等

分析:也是看过《深入JVM虚拟机》的基本都能回答道这个程度,其实到这个程度我已经比较期待了。同样小于10%。 

4.除了3外,还能讲清楚串行、并行(整理/不整理碎片)、CMS等收集器可作用的年代、特点、优劣势,并且能说明控制/调整收集器选择的方式

 

--------------------- 作者:Ontheroad_ 来源:CSDN 原文:https://blog.csdn.net/Ontheroad_/article/details/82905165?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值