《大厂面试现场》系列---这次一把搞定JVM面试(上篇)

232 阅读5分钟

d6.jpg

公众号:慕枫技术笔记

真正的大师永远怀着一颗学徒的心


引言

JVMJava工程师面试的必问基础知识之一,一般会在第一轮技术基础面试中会被问到。本文分为上下篇,力求最大程度还原面试现场,希望在大家准备面试的时候可以有所帮助,另外也希望通过这样的模拟面试能够帮助同学们理清技术面试的主要脉络。

面试开始了

铃铃铃,晚上七点十分,手机铃声突然响起,惊醒了本来趴在桌子上小憩一下的慕枫,睡眼朦胧的接到电话,懒散散的说了一句你好哪位?

电话那头: 请问是慕枫同学嘛?我这边是***,现在想跟你进行一场面试,现在有时间吗?

image.png

慕枫:(内心纠结面还是不面,还是决定面一下把,积累下经验也是好的)嗯嗯现在方便的,稍微等下出下办公室

电话那头: 我看你简历当中写了熟悉JVM以及有JVM优化的经验,那我们就先从JVM这块开始吧。

慕枫内心OS: 一万头草泥马奔腾而过,好久之前看的了,真应该在面试前再好好总结回顾下。

image.png

电话那头: JVM加载类的过程是怎样的,经历了那些阶段?

慕枫: JVM加载类的过程分为七大步骤,首先是通过类加载器将class信息加载到JVM中,JVM根据虚拟机规范对加载进来对class文件进行校验,只有校验通过后再继续后续的动作。在验证通过后,将会为代码中的一些变量分配对应堆内存空间。到了解析阶段,就是把符号引用替换为直接引用。接着是初始化阶段,需要进行一些赋值以及类初始化操作。接下来就是使用、卸载类了。

电话那头: 那你知道类加载器有哪些吗?

Bootstrap ClassLoader,主要负载加载java核心类库,也就是jdk目录下lib目录中的核心类库。Extension ClassLoader主要加载lib\ext目录下的扩展类库。Application ClassLoader,该加载器主要加载classpath环境变量所指定的路径中的类,这个类加载器实际负责加载程序猿编写的业务代码类到内存⾥。当然还有一些用户自定义的类加载器。

电话那头: 那你知道什么是双亲委派模型吗?

慕枫: 双亲委派模型简单理解就是一种类加载机制。在进行类加载时,首先并不自己去加载类,而是交由其对应的父类加载器去进行加载,如果父类加载器可以加载,则让父类加载器进行加载,如果父类加载器不能加载,那么只能自己进行类加载。

电话那头: 为什么这么设计呢,双亲委派模型的好处是什么呢?

慕枫: 双亲委派模型通过双亲委派模型来进行来加载的统一收口,可以避免类的重复加载。同时也保证了java核心api中定义类型不会被随意替换。

电话那头: 那么你知道Tomcat为什么要打破双亲委派模型呢?

慕枫: 每个Tomcat的webappClassLoader加载自己的目录下的class文件,不会传递给父类加载器。主要为了webapp中的 class和 lib需要相互隔离。

电话那头: 在JVM内存区域划分时,年轻代为什么要设置S0、S1区域?设置一个不行吗?

慕枫内心OS: (我的天,这个问题还真是有点刁钻,之前真没想过,得好好想想怎么回答)

慕枫: 我们可以反过来想一下,如果就只有一个S区会怎样,那么当发生MonitorGC时,除了Eden区需要进行垃圾回收,S区也会有一部分垃圾需要进行回收。那么此时复制算法不起作用了,因为没有区域可以进行复制了。那么会采用标记清除的方法进行垃圾回收,我们知道一旦进行标记清除必然会产生内存碎片问题。因此需要两个S区域,在Eden区域以及某个S区域需要进行GC时,可以将这两部分存活的对象通过复制算法复制到另外一个S区中,这样可以避免内存碎片的产生,高效利用内存空间。

电话那头: 恩恩,说的不错。你刚才说到minorGC,那么什么情况下进行minorGC?什么情况下进行Full GC知道吗?

慕枫: 对象进入JVM后,首先在新生代进行对象分配,当新生代内容空间不足以继续分配新对象时,将触发minorGC回收新生代中的垃圾对象。当老年代空间不足当时候、当老年代内存使用率超过一定设置阈值当时候也会触发。另外发⽣minorGC之前进⾏检查,如果“⽼年代可⽤的连续内存空间” < “新⽣代历次Young GC后升⼊⽼年代的对象总和的平均⼤⼩”,说明本次Young GC后可能升⼊⽼年代的对象⼤⼩,可能超过了⽼年代当前可⽤内存空间。通常情况下Full GC会伴随着minorGC。

以上是一些JVM基础知识的面试,在下篇将继续和面试官进行较量,希望可以给面试官一个良好的面试印象,加油吧,少年。

总结

对于JVM来说,面试官除了考察JVM模型结构、垃圾回收等基本知识,更重要等是考察面试者有没有线上环境等JVM调优经验,OOM产生后知道怎么去分析。