二面(高级面):jvm垃圾回收器的原理和选用
说实话,如果问这种问题,有点纯八股文面试的感觉了,因为原理完全不是java语言实现的,知道了也没什么用
首先得知道标量替换和逃逸分析,以及垃圾回收发生阶段
标量替换是需要开启的(jdk1.7之后标量替换和逃逸分析是自动开启),就是把一个对象分割成不可替换的基本类型,基本类型都在栈上创建,替换条件没深入研究过,
逃逸分析发生在编译阶段,就是编译的时候就已经做好标量替换和逃逸分析了,逃逸分析就是确定变量的作用域,有些变量可能是多线程的共享变量,多数对象是没有逃逸的
对于栈上空间是没有垃圾回收的,弹出栈就相当于回收了方法的局部变量产生的空间,所以需要标量替换,因为节约堆空间,减少gc的可能次数
第一点,要知道jvm是如何判定垃圾的
第一种判断方法叫可达性分析(GC Roots),由一系列根节点(静态对象、虚拟机栈、本地方法栈)出发,找寻他们指向的对象,会形成一条路径,不可达的对象会被标记,连续标记两次则全面回收(计数法就不说了,应该没有哪个版本的jvm会使用)
第二点,有哪些垃圾回收算法
第一种标记清除算法(Mark-Sweep),就是上一步最后,被标记位垃圾则进行回收,问题是造成内存碎片化
第二种复制算法(Copying),内存分成两块区域,活动区域和空闲区域,将活动区域的有效对象直接复制到空闲区域,然后将活动区域和空闲区域置换一下。问题是压缩部分内存,效率和对象数目成正比
第三种标记整理算法(Mark-Compact),将可存活对象向一端移动(解决碎片内存问题),直接清理掉另一端的可回收对象
垃圾回收器种类、特点、回收区域、使用的算法
第一代串行回收器serial 和 serial Old,这个目前应该没什么人用了,就是单线程的