java面试题:JVM的GC(垃圾回收)机制——详解

看了很多面试关于GC的回答,还是想写一个比较详细的答案,以便以后复习!

1.面试可答答案:请你讲一讲GC

答:
虚拟机堆中的内存分配:

  1. 虚拟机的垃圾收集采用“分代收集算法”,虚拟机中将堆的内存分为新生代和老年代
  2. 新生代又分为Eden区和Survive区(生存区),生存区又分为S0区和S1区。内存大小比例为8:1:1
  3. 老年代则只有一块内存区域
  4. 新生代主要存放生存周期较短的对象,而老年代存放的对象生存周期则一般较长

GC的触发机制以及过程: 后面会讲GC的实现

  1. 大多数的对象在新生代被创建, 准确的来说是在Eden区创建,当Eden区内存满时触发Minor GC,当Minor GC一次之后仍然存活的对象转移至S0区
  2. 当S0区内存不够时再次触发GC,将仍存活的对象转移至S1区,之后清空S0区,也就是说S0和S1区会不断的颠倒,但是却一直会保证一个区是空的,因为Eden区存活的对象会转移进来!
  3. 在新生代经过多次Minor GC仍然存活的对象则转移到老年代。转移的触发是为每个对象增加了一个年龄阈值的属性
    (N = MaxTenuringThreshold),默认为15,也就是说当对象的年龄超过了这个阈值,就会被转移到老年代
  4. 当老年代的内存不足以容纳从新生代转移到老年代的对象内存时,就会触发full GC

GC实现:根搜索算法

  • 无论是Minor GC 还是 Full GC,其底层原理实现都是基于根搜索算法实现的,只不过在搜索完之后如何进行内存转移和清理各有不同。
  • 根搜索算法是从离散数学中的图论引入的,程序把所有引用关系看作一张图,从一个节点GC ROOT 开始,寻找对应的引用节点,找到这个节点后,继续寻找这个节点的引用节点。当所有的引用节点寻找完毕后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。
    在这里插入图片描述
  • 根据上图我们就可以知道需要被清理的对象为红色节点

Minor GC实现:复制算法

  • 由于新生代中的对象都是朝生夕死的,所以每次需要转移的对象内存不是很大,所以使用复制算法
  • 它将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当这块内存需要进行垃圾回收时,会将此区域还存活着的对象复制到另一块上面,然后再把已经使用过的内存区域一次清理掉。这样做的好处是每次都是对整个半区进行内存回收,内存分配时也就不需要考虑内存碎片等的复杂情况,只需要移动堆顶指针,按顺序分配即可。
  • 其实MinGC实现复制算法的过程就是我们刚刚提到的新生区中的对象的转移机制

Full GC实现:标记整理算法

  • 由于老年代中的对象生存周期较长,如果使用复制算法的话效率就会降低,所以使用标记清理算法
  • 标记清理算法的实现就是在找到存活对象之后,将其往内存的一端进行移动,最后我们只需要去清理另一端的内存边缘即可。
  • 但是有一个常见的问题我还是没弄懂,会问到老年代GC之后的碎片要不要整理?如何整理?

如果是面试官让你讲一讲GC,那么就可以按照这个顺序进行叙述,当然了也会有一些细节的问题,其实答案都在这个过程中,下面就举一些常见的面试题

2.常见面试题:

2.1 哪些对象可以作为GC Root对象

(1)虚拟机(JVM)栈中引用对象

(2)方法区中的类静态属性引用对象

(3)方法区中常量引用的对象(final 的常量值)

(4)本地方法栈JNI的引用对象

2.2 Minor GC什么时候触发?

  • 虚拟机在进行minorGC之前会判断老年代最大的可用连续空间是否大于新生代的所有对象总空间

  • 如果大于的话,直接执行minorGC

  • 如果小于,判断是否开启HandlerPromotionFailure,没有开启直接FullGC

  • 如果开启了HanlerPromotionFailure, JVM会判断老年代的最大连续内存空间是否大于历次晋升的大小,如果小于直接执行FullGC

  • 如果大于的话,执行minorGC

  • 如果记不住的话就回答:Eden区满了minorGC

2.3 Full GC什么时候触发?

  • 老年代空间不足
    如果创建一个大对象,Eden区域当中放不下这个大对象,会直接保存在老年代当中,如果老年代空间也不足,就会触发Full GC。为了避免这种情况,最好就是不要创建太大的对象。

  • 持久代空间不足
    如果有持久代空间的话,系统当中需要加载的类,调用的方法很多,同时持久代当中没有足够的空间,就出触发一次Full GC

  • YGC出现promotion failure
    promotion failure发生在Young GC, 如果Survivor区当中存活对象的年龄达到了设定值,会就将Survivor区当中的对象拷贝到老年代,如果老年代的空间不足,就会发生promotion failure, 接下去就会发生Full GC.

  • 统计YGC发生时晋升到老年代的平均总大小大于老年代的空闲空间
    在发生YGC是会判断,是否安全,这里的安全指的是,当前老年代空间可以容纳YGC晋升的对象的平均大小,如果不安全,就不会执行YGC,转而执行Full GC。

  • 显示调用System.gc

  • 如果记不住答:升到老年代的对象大于老年代剩余空间full gc,或者小于时被HandlePromotionFailure参数强制full gc

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值