Java虚拟机的三个垃圾收集算法

Java虚拟机的三个垃圾收集算法

标记–清除、标记–复制、标记–整理

GC Roots:它是可达性分析的起点,哪些可以作为GC Roots的节点?

	1. 栈帧局部变量表的引用对象
	2. 方法区中静态引用的对象(引用类型静态变量)
	3. 方法区中常量引用的对象
	4. 本地方法中引用的对象
	5. Java虚拟机的内部引用,如基本数据类型的Class对象、异常对象、类加载器
	6. 被同步锁(Synchronized)持有的对象
	7. 反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存

如何判定对象存活还是死亡

​ 如果在进行可达性分析后没有与GC Roots相连,那么该对象会被第一次标记,随后会进行一次筛选,条件是:是否有必要执行finalize()方法,假如对象没有覆盖finalize()方法,活着finalize()方法已经被虚拟机调用过,那么虚拟机将这两种情况都视为没有必要执行。确认对象死亡后,该对象会被放到一个名为F-Queue的队列中,稍后由一条虚拟机创建的低调度优先级的Finalizer线程去执行它们的finalize()方法。

标记–清除:

它是最早出现也是最基础的垃圾收集算法。

首先标记出需要回收的对象,标记完成后,统一回收掉所有被标记的对象(也可以标记活着的对象)

两个主要缺点:

1. 执行效率不稳定,当堆中存在大量对象,而且大部分是需要回收的,这时需要大量的标记和清除动作
2. 空间碎片化

标记–复制(优先采用它回收新生代):

将堆内存划分为两块,每次使用其中一块。垃圾收集时,将活着的对象复制到另一块上面,然后将使用的这块全部回收,复制到另一块上面的对象是连续排列的,也就没有了空间碎片化问题,缺点很明显空间少了一半。对象存活率高,该算法效率也很低

但根据“新生代的对象有98%熬不过第一轮收集”,就有了“Appel式回收”,

即HotSpot默认的8:1:1(Eden:Survivor0:Survivor1),每次使用Eden加一个Survivor,也就只有10%的空间闲置

标记–整理(老年代):

标记完成后,将活着的对象往内存空间的一端移动,然后将另一端清理掉。移动对象需要修正引用而且要Stop The World

おすすめ

転載: blog.csdn.net/qq_42682745/article/details/120995706