面试题32:垃圾收集器——G1

2023-05-09 21:39:45 浏览数 (2)

  • -XX: UseG1GC

标记打开G1收集器开关


【概述】

  • G1回收器是JDK1.7正式使用的回收器,它的目标是来取代CMS回收器。
  • 它属于分代回收器,也使用了分区算法。
  • 它的优点有如下几个方面
    • 1> 它是多个线程同时执行GC操作的,可以最大限度利用多cpu计算能力。
    • 2> 虽然它在初始标记、重新标记和独占清理这三个阶段需要STW。但是,对于整体GC过程来说,是可以与应用程序并行执行的。
    • 3> 它即可以负责年轻代的GC,也可以负责老年代的GC。实现了一个回收器对多代的完全统治。
    • 4> G1不是采用CMS这种标记清除算法,它每次回收都会有效地复制对象,从而减少内存碎片。
    • 5> G1支持分区算法来执行垃圾回收,采取局部回收操作,它对内存进行了划分区域,每次GC收集只针对其中几个区域,极大减少由GC导致的停顿时间。

【G1的收集过程分为4个阶段】

  • 阶段1:新生代GC
    • 新生代GC的主要工作就是回收eden区和survivor区。
    • 一旦eden区被占满,新生代GC就会启动。回收后,所有的eden区都应该被清空,而survivor区会被收集一部分数据,但是应该至少仍然存在一个survivor区。
  • 阶段2:并发标记周期 (过程与CMS很类似)
    • 初始标记STW
      • 标记从根节点直接可到达的对象。
      • 这阶段会伴随一次Young GC,会产生STW(全局停顿),应用程序会停止执行。
    • 根区域扫描
      • 由于Young GC的发生,所以初始标记后,eden被清空,存活对象放入Survivor区。然后本阶段,则扫描survivor区,标记可直达老年代的对象。本阶段应用程序可以并行执行。但是,根区域扫描不能和YoungGC同时执行(因为根区域扫描依赖survivor区的对象,而新生代GC会修改这个区域),因此如果恰巧在此时需要进行YoungGC,GC就需要等待根区域扫描结束后才能进行,如果发生这种情况,这次YoungGC的时间就会延长。
    • 并发标记
      • 用来再次扫描整个堆的存活对象,并做好标记。与CMS类似,该阶段可以被一次Young GC打断。
    • 重新标记STW
      • 本阶段也会发生STW,应用程序会停止执行。由于并发标记阶段中,应用程序也是并发执行的,所以本阶段,对标记结果进行最后的修正处理。
    • 独占清理STW
      • 本阶段也会发生STW,应用程序会停止执行。它用来计算各个区域的存活对象和GC回收比例,然后进行排序,从而识别出可以用来混合收集的区域。该阶段给出了需要被混合回收的区域并进行了标记,那么在混合收集阶段,是需要这些信息的。
    • 并发清理
      • 本阶段会去识别并清理那些完全空闲的区域。
  • 阶段3:混合收集
    • 在第二步的并发标记周期过程中,虽然有部分对象被回收,但是总体回收比例还是比较低的。
    • 由于G1已经明确知道哪些区域含有比较多的垃圾比例,所以就可以针对比例较高的区域进行回收操作。
    • G1会优先回收垃圾比例较高的区域,因为这样性价比会比较高。
    • 这个阶段叫作混合回收,是因为这段时期,新生代和老年代GC都会同时进行。
    • 那么因为新生代GC后,eden区必然被清空,此外被标记为垃圾比例最高的区域也被清理。
    • 被清理区域中存活对象就会被移动到其他的区域,这样的好处就是可以减少空间碎片。
  • 阶段4:Full GC(不是一定会执行,看情况来定)
    • 由于GC回收过程,是与应用程序并发执行的,所以,如果在吞吐量很大的场景下,回收过程中内存不足,那么就会触发一次Full GC。

0 人点赞