返回

揭开JVM GC子系统的奥秘:从基础算法到种类详解

后端

引言

在前面五个章节的分析之后,对于JVM的大部分子系统都已经阐述完毕,在本文中将开始对JVM的GC子系统进行全面阐述,GC机制也是JVM的重中之重,调优、监控、面试都逃不开的JVM话题。

对象存活判定算法

对象存活判定算法用于确定哪些对象是存活的,哪些对象是死亡的。GC算法正是基于对象存活判定算法的结果来进行垃圾回收。

引用计数算法

引用计数算法是最简单的一种对象存活判定算法。每个对象都有一个引用计数器,每当一个对象被引用时,其引用计数器加1;每当一个对象的引用被释放时,其引用计数器减1。当一个对象的引用计数器为0时,说明该对象不再被任何对象引用,因此可以被回收。

可达性分析算法

可达性分析算法是目前最常用的对象存活判定算法。可达性分析算法从GC Roots开始,沿引用链向下搜索,如果某个对象不能从GC Roots到达,则说明该对象是死亡的,可以被回收。

GC Roots包括:

  • JVM栈中的局部变量
  • 方法区中的静态变量
  • 本地方法栈中的JNI引用
  • 全局变量
  • 常量池中的引用
  • 永久代中的引用

GC算法

GC算法用于回收死亡的对象。GC算法有很多种,但最常见的包括:

标记清除算法

标记清除算法是最简单的一种GC算法。标记清除算法首先标记所有存活的对象,然后清除所有未标记的对象。标记清除算法的缺点是会产生内存碎片。

标记整理算法

标记整理算法与标记清除算法类似,但标记整理算法在清除死亡对象后会将存活的对象重新整理到内存中,从而消除内存碎片。

复制算法

复制算法将内存划分为两个相等大小的区域。当一个区域被填满时,GC算法将存活的对象复制到另一个区域,然后清除第一个区域中的所有对象。复制算法的优点是不会产生内存碎片,但复制算法的缺点是需要两倍于实际所需的空间。

分代收集算法

分代收集算法是目前最常用的GC算法。分代收集算法将对象划分为不同的代,如年轻代、年老代、永久代等。年轻代的对象存活时间较短,年老代的对象存活时间较长。分代收集算法对年轻代使用复制算法,对年老代使用标记整理算法。分代收集算法的优点是效率高、内存碎片少。

增量收集算法

增量收集算法是一种在应用程序运行时进行垃圾回收的算法。增量收集算法的优点是不会造成应用程序的长时间停顿,但增量收集算法的缺点是效率较低。

STW

STW(Stop The World)是指GC算法在执行过程中会暂停应用程序的所有线程。STW是GC算法的一个主要缺点,因为STW会造成应用程序的长时间停顿。

GC种类

GC种类有很多,但最常见包括:

串行GC

串行GC是一种单线程的GC算法。串行GC的优点是简单、高效,但串行GC的缺点是会造成应用程序的长时间停顿。

并行GC

并行GC是一种多线程的GC算法。并行GC的优点是不会造成应用程序的长时间停顿,但并行GC的缺点是效率较低。

并发GC

并发GC是一种在应用程序运行时进行垃圾回收的GC算法。并发GC的优点是不会造成应用程序的长时间停顿,但并发GC的缺点是效率较低。

总结

GC机制是JVM的核心组成部分之一。GC算法的正确选择和调优对于JVM的性能至关重要。在本文中,我们对JVM的GC子系统进行了全面的阐述,希望能够对读者有所帮助。