【三色标记】

简介: 【三色标记】

JVM三色标记

JVM三色标记是Java虚拟机在执行垃圾回收时使用的一种算法。这种算法将所有对象分为三种颜色:白色、灰色和黑色。初始时,所有对象都是白色的。在执行垃圾回收前,Java虚拟机会将某些对象标记为灰色,表示这些对象可能需要被回收,但是它们的引用对象还没有被标记为黑色。在垃圾回收期间,Java虚拟机会遍历所有灰色对象并将它们标记为黑色。标记为黑色的对象表示这些对象的引用关系已经被垃圾回收器完全追踪,它们不再需要被回收。

下面是一个示例程序,演示垃圾回收器使用三色标记算法进行垃圾回收的过程:

import java.util.ArrayList;
import java.util.List;
public class ThreeColorMarkingExample {
    private static final int LIST_SIZE = 1000000;
    private static final int LOOP_COUNT = 3;
    public static void main(String[] args) {
        // 创建一个白色对象列表
        List<Object> whiteList = new ArrayList<>();
        for (int i = 0; i < LIST_SIZE; i++) {
            whiteList.add(new Object());
        }
        // 执行循环,模拟引用关系
        for (int i = 0; i < LOOP_COUNT; i++) {
            List<Object> grayList = new ArrayList<>();
            for (int j = 0; j < LIST_SIZE; j++) {
                // 白色对象引用灰色对象
                grayList.add(whiteList.get(j));
            }
            // 将灰色列表标记为灰色
            markGray(grayList);
        }
        // 执行垃圾回收
        System.gc();
        // 输出垃圾回收前后的对象数量
        System.out.println("before gc: " + whiteList.size() + " objects");
        removeGrayObjects(whiteList);
        System.out.println("after gc: " + whiteList.size() + " objects");
    }
    private static void markGray(List<Object> grayList) {
        for (Object obj : grayList) {
            // 将灰色对象标记为灰色
            if (!isGray(obj)) {
                setGray(obj);
                // 将灰色对象引用的白色对象标记为灰色
                markGray(getReferencedObjects(obj));
            }
        }
    }
    private static void setGray(Object obj) {
        // 将对象标记为灰色
    }
    private static boolean isGray(Object obj) {
        // 判断对象是否为灰色
        return false;
    }
    private static List<Object> getReferencedObjects(Object obj) {
        // 获取对象引用的其他对象
        return new ArrayList<>();
    }
    private static void removeGrayObjects(List<Object> whiteList) {
        for (int i = 0; i < whiteList.size(); i++) {
            Object obj = whiteList.get(i);
            // 将灰色对象从白色列表中删除
            if (isGray(obj)) {
                whiteList.remove(i);
                i--;
            }
        }
    }
}

在上面的示例程序中,我们创建了一个白色对象列表,然后执行了三次循环,每次循环将白色对象引用到灰色对象中,使用markGray方法将灰色对象标记为灰色。最后执行System.gc()方法执行垃圾回收,然后使用removeGrayObjects方法将列表中的灰色对象删除。最终输出垃圾回收前后的对象数量。

请注意,示例程序中的setGrayisGraygetReferencedObjects方法是伪代码,需要根据具体实现进行实现。此外,示例程序中的内存消耗是比较大的,实际应用中应该尽量避免创建过多的对象。

小故事

有一只狗狗,它追着一支彩色的球跑来跑去。当球停下来的时候,狗狗也会停下来,但是它的尾巴还在摇摆。这时,一个人走过来,拿起了球,狗狗就开始追着这个人走了。

这个故事可以用来解释JVM的三色标记垃圾回收算法。JVM中的对象就像球和狗狗一样,GC线程就像人一样去收集垃圾。在JVM中,GC线程会对所有的对象进行三色标记:白色、灰色和黑色。

白色表示对象还未被扫描,灰色表示对象已经被扫描但还有引用对象未被扫描,黑色表示对象已经被扫描且引用的对象也已经被扫描。

当GC线程开始扫描时,所有的对象都是白色的。当GC线程扫描到一个对象时,它会将该对象标记为灰色,并将该对象的引用对象标记为灰色。如果该对象的所有引用对象都已被扫描,该对象会被标记为黑色。当GC线程完成扫描后,所有未被标记为黑色的对象都会被清除。

这个过程就像狗狗追球的过程,当球停下来的时候,狗狗停下来,但是尾巴还在摇摆,表示还有一些对象未被扫描。当人开始走时,狗狗开始追着人走,表示GC线程在扫描未被标记的对象。当人走过所有的地方,狗狗也跟着走过去,表示GC线程已经扫描完所有的对象。


相关文章
|
3月前
|
存储 算法 Java
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
【JVM】垃圾释放方式:标记-清除、复制算法、标记-整理、分代回收
77 2
|
7月前
|
Java
Java自定义注解:优雅的代码标记
Java自定义注解:优雅的代码标记
51 1
|
7月前
|
算法 Java
三⾊标记法若不被STW保护可能会导致对象丢失,⽩⾊对象被⿊⾊对象引⽤,灰⾊对象对⽩⾊对象的引⽤丢失(为什么需要这个条件),导致对象丢失。
三⾊标记法若不被STW保护可能会导致对象丢失,⽩⾊对象被⿊⾊对象引⽤,灰⾊对象对⽩⾊对象的引⽤丢失(为什么需要这个条件),导致对象丢失。
|
7月前
|
存储 算法 安全
JVM-内存划分-垃圾回收器-回收算法-双亲委派-三色标记
JVM-内存划分-垃圾回收器-回收算法-双亲委派-三色标记
|
8月前
|
算法 Java
三色标记的大致流程可以讲一下吗
三色标记的大致流程可以讲一下吗
|
存储 算法 安全
深入学习 GC 算法 - 标记清除算法
深入学习 GC 算法 - 标记清除算法
4475 2
深入学习 GC 算法 - 标记清除算法
|
算法 安全 Java
|
算法 安全 Java
阿里二面:JVM 的三色标记算法你了解吗?
阿里二面:JVM 的三色标记算法你了解吗?
121 0
|
算法 安全 Java
你对JVM三色标记的理解嘛?
你对JVM三色标记的理解嘛?
117 0
你对JVM三色标记的理解嘛?
|
算法 Java
25-【扩展补充】JVM 三色标记 增量更新 原始快照
本文将介绍JVM中的三色标记算法、增量更新和原始快照的概念。 首先,我们将深入探讨JVM中的三色标记算法。这种垃圾回收算法基于可达性分析,将对象分为三个状态:白色、灰色和黑色。通过标记对象的可达性,垃圾回收器可以确定哪些对象可以安全地回收,从而有效地管理内存。 接下来,我们将介绍增量更新技术。增量更新是一种垃圾回收的优化方法,它将垃圾回收过程分为多个阶段,并与应用程序交替执行。通过这种方式,增量更新可以减少垃圾回收的停顿时间,提高应用程序的响应性能。
251 0