如果读完觉得有收获的话,欢迎点赞加关注
从 一文的阅读量和点赞程度可以发现,貌似大家更喜欢这类文章,也许是技术型的文章看着比较的枯燥,这些只是我近段时间求职面试时所遇到的一些问题,整理出来希望对有需要的同学提供帮助,可以更系统的去学习各个知识点。
这块内容并非每个面试官都会问,但是如果是应聘高级职位的话,这一环节是不可缺少的,面试的难易程度也不一样,有些面试官或许让你讲讲虚拟机的内存模型即可,有些也会让你解释垃圾回收的实现,当然也会有虚拟机调优的实战经验,线上问题排查等等。
场景对话:
面试官:Java虚拟机有了解么?
我:恩,略有接触过...(水哥说过,话不能说太满,容易打脸)
面试官:那你先讲讲它的内存模型吧
我:Java堆,Java栈,程序计数器,方法区,1.7的永久代,1.8的metaspace....(噼里啪啦概念讲一通,简短描述下每个内存区的用途,能想到的都讲出来,不要保留,不要等面试官问 “还有吗?”)
面试官:好,一般Java堆是如何实现的?
我:在HotSpot虚拟机实现中,Java堆分成了新生代和老年代,我当时看的是1.7的实现,所有还有永久代,新生代中又分为了eden区和survivor区,survivor区又分成了S0和S1,或则是from和to,(这个时候,我要求纸和笔,因为我觉得这个话题可以聊蛮长时间,又是我比较熟悉的...一边画图,一边描述),其中eden,from和to的内存大小默认是8:1:1(各种细节都要说出来...),此时,我已经在纸上画出了新生代和老年代代表的区域
面试官:恩,给我讲讲对象在内存中的初始化过程?
我:(千万不要只说,新对象在Java堆进行内存分配并初始化,或是在eden区进行内存分配并初始化)要初始化一个对象,首先要加载该对象所对应的class文件,该文件的数据会被加载到永久代,并创建一个底层的instanceKlass对象代表该class,再为将要初始化的对象分配内存空间,优先在线程私有内存空间中分配大小,如果空间不足,再到eden中进行内存分配...^&&*%
面试官:恩,好,说下YGC的大概过程...
我:先找出根对象,如Java栈中引用的对象、静态变量引用的对象和系统词典中引用的对象等待,把这些对象标记成活跃对象,并复制到to区,接着遍历这些活跃对象中引用的对象并标记,找出老年代对象在eden区有引用关系的对象并标记,最后把这些标记的对象复制到to,在复制过程还要判断活跃对象的gc年龄是否已经达到阈值,如果已经达到阈值,就直接晋升到老年代,YGC结束之后把from和to的引用互换(能多说点就多说点,省的面试官再提问,我把老年代的cms回收也大致说了一遍,以为面试官会跳过这个话题了,还是太年轻了)。
面试官:你刚刚说到在YGC的时候,有些对象可能会发生晋升,如果晋升失败怎么处理?
我:....(断片了几秒钟,我记得我分析过这段代码的,但是印象不深刻了)我记得在标记阶段时,会把对象和对应的对象头数据保存在两个栈中,如果晋升失败的话,就把该对象的对象头复原...
面试官:那你在实际项目中有碰到这种情况么,会导致什么问题?
我:...(这我真没有遇到过)对,有遇到过一次,在分析gc日志的时候,发现YGC发生之后,日志显示gc后的内存变大了,后来查出来是因为对象的晋升失败造成的。(我隐约记得看过笨神的一篇文章,回答的心里很虚)
面试官:(没有反驳,继续问)有过虚拟机性能调优的经验么?
我:(说实话,调优经验真的不多)恩,有一点吧,不是很足,就是我们XX项目上线的时候,发现YGC特别的频繁^^&^8&,通过调整新生代的大小(线上环境的虚拟机参数是默认的),同时检查业务逻辑代码&*&$$~~!
面试官:恩?还有么?
我:(面试这么久,好怕面试官的下一句是 “恩?还有么?”,显然面试官还不满足我的回答,但是我也只能答到这个地步了...)恩,经验确实有限,目前就根据这个项目做过一些相关的优化。
面试官: 。。。。。。
我:。。。。。。
面试官: 那我们看看别的吧。
关于虚拟机方面的文章,我针对hotSpot的实现写了一些分析,感兴趣的同学可以看看,这些文章看着确实有点枯燥。
来源: http://www.tuicool.com/articles/neEbqiQ