✅为什么G1从JDK 9之后成为默认的垃圾回收器?

典型回答

G1,Garbage First,是CMS的改进版,解决了CMS内存碎片、更多的内存空间等问题。总之,G1是一个先进的垃圾收集器,它可以提高系统的吞吐量,降低停顿的频率,并且可以有效管理大型堆。在JDK 9之后,G1成为了默认的垃圾回收器,主要是因为他有以下优势:

  1. 并发回收:G1能充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者CPU核心)来缩短Stop The World的停顿时间。部分其他收集器原本需要停顿Java线程执行的GC动作,G1收集器仍然可以通过并发的方式让Java程序继续执行。

✅什么是三色标记算法?

  1. 分代收集:分代概念在G1中依然得以保留。虽然G1可以不需要其它收集器配合就能独立管理整个GC堆,但它能够采用不同的方式去处理新创建的对象和已经存活了一段时间、熬过多次GC的旧对象以获取更好的收集效果。也就是说G1可以自己管理新生代和老年代了。
  2. 空间整合:由于G1使用了独立区域(Region)概念,G1从整体来看是基于标记-整理算法实现收集,从局部(两个Region)上来看是基于标记-复制算法实现的,但无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片。
  3. 可预测的停顿:这是G1相对于CMS的另一大优势,降低停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
  4. 支持热插拔:G1可以在运行时动态调整堆的大小,以适应不同的内存需求。

与其它收集器相比,G1变化较大的是它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留了新生代和老年代的概念,但新生代和老年代不再是物理隔离的了它们都是一部分Region(不需要连续)的集合。

同时,为了避免全堆扫描,G1使用了Remembered Set来管理相关的对象引用信息。当进行内存回收时,在GC根节点的枚举范围中加入Remembered Set即可保证不对全堆扫描也不会有遗漏了。

Garbage First (G1) 是一种面向大型内存环境的垃圾回收算法。因此,G1适合在以下场景中使用:

  1. 大型内存环境:G1针对大型内存环境进行了优化,因此对于使用了大量内存的应用程序来说(超过4G),G1是一个更好的选择。
  2. 对应用程序响应时间敏感的场景:G1通过分配多线程来进行垃圾回收,以最大限度地减少回收时应用程序的暂停时间。
  3. 对内存使用效率敏感的场景:G1可以更好地评估哪些内存空间可以释放,以此来提高内存的利用率。
  4. 动态内存需求的场景:G1支持热插拔,可以在运行时动态调整堆的大小,以适应不同的内存需求。
  5. 要求回收时间具有可预测性的场景:G1使用固定的内存分配块来管理堆内存,这使得其在回收时间上具有更高的可预测性。

所以,如果应用程序需要在大型内存环境下运行,同时对内存使用效率和应用程序的响应时间敏感,那么G1是一个更好的选择。

原文: https://www.yuque.com/hollis666/xkm7k3/hgquufzt6m9psmtp