V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
linwu
V2EX  ›  Java

CMS 垃圾收集器

  •  
  •   linwu · 2020-03-08 05:18:38 +08:00 · 3994 次点击
    这是一个创建于 1719 天前的主题,其中的信息可能已经有所发展或是发生改变。

    CMS 垃圾收集器垃圾收集大概分为 4 个阶段:

    ( 1 )初始标记
    ( 2 )并发标记预清除
    ( 3 )重新标记
    ( 4 )并发清除
    

    在 ( 2 )并发标记预清除阶段,因为还有用户线程在进行,可能会有对象引用的更改, 所以需要( 3 )重新标记 重新修正存活对象

    那么在( 4 )并发清除阶段(也是有用户线程在进行), 清除的时候,如果用户线程更改了对象的引用,导致原先一个应该不算存活的对象存活了 那么清除又将该对象清除了怎么办?

    网上看了很多答案,没有说的很清楚,都是扯到了浮动垃圾上,浮动垃圾应该算是新产生的对象吧,也不会被清除,就是因为不被清除,才可能导致新的 GC

    也看了《深入理解 Java 虚拟机》也没有一个很好的解释。

    希望理解的朋友可以解答下

    20 条回复    2020-03-08 17:10:49 +08:00
    btnokami
        1
    btnokami  
       2020-03-08 05:29:05 +08:00 via iPhone
    想象力有限,楼主能举个已经丢失引用的对象被再次引用的例子吗
    linwu
        2
    linwu  
    OP
       2020-03-08 05:57:52 +08:00
    public static void main(String[] args) {
    A a = new A();
    a.b = new B();

    C c = new C();
    c.b = a.b;

    a = null;
    }

    class A {

    ...
    }

    class A {
    ...
    }

    class A {
    ...
    }
    linwu
        3
    linwu  
    OP
       2020-03-08 06:00:27 +08:00
    class A {
    B b;
    ...
    }

    class C {
    B b;
    ...
    }

    class B {
    ...
    }
    linwu
        4
    linwu  
    OP
       2020-03-08 06:06:05 +08:00
    好像不行哈哈,那书上说的"标记期间应用可能被正在运行并更新引用"是什么意思呢?弄不懂
    btnokami
        5
    btnokami  
       2020-03-08 07:20:24 +08:00
    @linwu 这个更新引用并不是指失去引用的对象被重新引用吧,而是指在运行期间这个对象有了新的引用,这样在做 tri-color marking 的时候颜色可能会被修改。
    yafoo
        6
    yafoo  
       2020-03-08 07:46:23 +08:00 via Android   ❤️ 1
    以为你专门收集整理过时的 cms 系统呢
    sagaxu
        7
    sagaxu  
       2020-03-08 09:40:48 +08:00 via Android
    几年前 cms 就被废弃了,怎么还有人考古?
    Jacky23333
        8
    Jacky23333  
       2020-03-08 10:34:47 +08:00 via Android
    @sagaxu 面试要问
    bbao
        9
    bbao  
       2020-03-08 10:40:59 +08:00
    @sagaxu 现在普遍 G1 了?
    liuming
        10
    liuming  
       2020-03-08 11:22:27 +08:00
    "标记期间应用可能被正在运行并更新引用"指的是在初始标记时还存活但到重新标记时成垃圾了的情况吧
    sagaxu
        11
    sagaxu  
       2020-03-08 11:51:25 +08:00 via Android   ❤️ 1
    @bbao 2015 年提出废弃 cms,2017 年 Java 9 默认 g1,cms 则被标记为废弃。2019 年提出要删除 cms 相关代码,下下周将要发布的 Java 14 不再包含 cms 相关代码,从此用不了 cms。

    @Jacky23333 有些面试还喜欢问 Java 7 和 Java 8 的 map 实现有什么不同。这种喜欢考古和面试专用 100 问的面试,反而简单,不用动脑,背宝典可破。
    bbao
        12
    bbao  
       2020-03-08 14:25:24 +08:00
    @sagaxu 仁兄,现在还是否用 java,生产环境 JVM 配置的垃圾收集是什么?
    rrfeng
        13
    rrfeng  
       2020-03-08 14:53:54 +08:00 via Android
    CMS 有一个 stw ( stop the world )阶段,意思是啥都不干只进行垃圾收集的。
    sagaxu
        14
    sagaxu  
       2020-03-08 15:09:28 +08:00 via Android
    @bbao 生产环境 g1,gc 只设置了两个参数,Xmx 和 MaxGCPauseMillis。
    Jacky23333
        15
    Jacky23333  
       2020-03-08 15:17:26 +08:00 via Android
    如果一个对象被判定为死亡,也就是不可达的,那你还能通过什么办法去更改到这个对象的引用,也就是说 a = new Instance();a = null,那你还能够怎样去访问到 Instance()并更改它的引用呢。所以应该不会出现你所说的问题
    bbao
        16
    bbao  
       2020-03-08 15:17:40 +08:00
    @rrfeng 第一次初始标记和重新标记都是 STW,标记对象,并不进行垃圾收集。在预清理阶段会有 minor gc 的发生,减少重新标记时对象的数量和减少 stw 时间。
    zrc
        17
    zrc  
       2020-03-08 15:23:08 +08:00
    这些线程都是到了 safepoint 的时候才 stw 吧,可能和 safepoint 的定义点有关
    gaius
        18
    gaius  
       2020-03-08 15:57:55 +08:00 via Android
    再次标记是扫并发标记改变阶段改变的对象,我的理解是对象地址,如果不修正一下会因为地址错误清理不了,应该不会出现垃圾又被重新引用的情况吧?
    optional
        19
    optional  
       2020-03-08 16:08:05 +08:00
    因为是并发标记,有些引用在 register 和 cpu cache 里吧
    Goooogle
        20
    Goooogle  
       2020-03-08 17:10:49 +08:00
    如何判断一个对象是否还在被引用?
    JVM 会从栈帧、常量区、方法区、Native 区中的引用开始进行可达性分析,当一个对象不可达后,才能会标记为可回收,放入 finalize 队列,去执行 finalize 方法。当执行完 finalize 方法后(或许不会执行),如该对象还是不可达,那这个对象就真的无法再被代码访问到。(毕竟 Java 不能直接操作指针)

    到于浮动垃圾,是指在进行可达性分析时,新生成了对象,或者是原有的可达对象在经过一段时间后引用引用状态变成不可达。


    所以根本问题在于:当对象标记为不可达后,真的就不会再回来了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1173 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 18:12 · PVG 02:12 · LAX 10:12 · JFK 13:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.