首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么GC需要在某些标记阶段停止mutator线程?

GC(垃圾回收)需要在某些标记阶段停止mutator线程的原因是为了保证垃圾回收的准确性和一致性。

在标记阶段,GC需要遍历整个堆内存,标记出所有存活的对象,以便后续回收未标记的对象。如果在标记阶段mutator线程继续执行,可能会导致以下问题:

  1. 并发标记:如果mutator线程在标记过程中修改了对象的引用关系,那么GC可能会漏标或错误标记对象,导致回收了仍然存活的对象,或者保留了已经死亡的对象。为了避免这种情况,GC需要在标记阶段停止mutator线程,以保证标记的准确性。
  2. 对象分配:如果mutator线程在标记阶段继续分配新的对象,那么GC可能会漏标这些新对象,导致回收了仍然存活的对象。为了避免这种情况,GC需要在标记阶段停止mutator线程,以确保所有存活对象都被正确标记。
  3. 对象移动:某些GC算法(如压缩算法)需要将存活对象移动到连续的内存空间中,以便更高效地分配内存和提高内存访问性能。如果mutator线程在标记阶段继续执行,可能会导致对象移动过程中的数据不一致性或错误引用,导致程序崩溃或产生难以调试的错误。为了避免这种情况,GC需要在标记阶段停止mutator线程,以确保对象移动的正确性和一致性。

综上所述,GC需要在某些标记阶段停止mutator线程,以保证垃圾回收的准确性、一致性和可靠性。在腾讯云中,推荐使用的云计算产品是腾讯云的云服务器(ECS),详情请参考:https://cloud.tencent.com/product/cvm

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

深入解析java虚拟机:垃圾回收,最大并发标记清除垃圾回收器

Old GC大部分过程允许Mutator线程GC线程一起进行,此时Mutator线程无须停止,这种方式称为并发垃圾回收,所使用的算法称为并发标记清除算法。...为了将它改造为并发算法,CMS GC标记清除算法细分为初始标记、并发标记、预清理、可中断预清理、重新标记、并发清理,重置几个阶段,其中只有初始标记和重新标记需要STW,其他最耗时的阶段允许GC线程Mutator...Mutator线程GC一起工作,在STW的两个阶段,垃圾回收器还可以充分发挥多核处理器的优势,使用多个线程进行回收工作,减少STW时间。...如果上一阶段并发标记过程中Mutator线程修改了对象引用关系,比如创建了新生代指向老年代的引用,那么预清理可以发现这些修改,并标记老年代的对象图。...重新标记 重新标记(FinalMarking)过程会再次停止全部Mutator线程(STW),只允许垃圾回收线程

48610

深入Android Runtime:并发复制GC

_ = nullptr; } Google IO 2017中介绍的暂停阶段对应的图如下: 暂停用户线程mutator线程)是通过mutator_lock_来实现的。...如果GC线程需要挂起其他mutator线程,就会将所有mutator线程的suspend_count加一,当mutator线程运行到GC check point(比如jni函数执行结束)的时候,就会检查这个标志...GC线程mutator线程之间的关系可以通过以下代码注释描述来了解: 执行到MarkingPhase时,基本上所有的可达对象都已经被标记完了,此时标记栈都已经被处理完。...GC线程(collector线程)需要在某个必要的时刻(GC safe point)暂停所有的mutator线程,然后进行对象标记操作。...这样,只要mutator线程访问堆上的某个对象,都会被GC线程监控。

1.5K20
  • 深入解析java虚拟机:垃圾回收,垃圾回收基础概述

    它从GCRoot出发标记存活对象,清理未被标记的对象,这种方式又被称为追踪式回收。Java的所有垃圾回收器都使用追踪式回收,只是具体的算法细节不尽相同。...由于Mutator线程访问不可读不可写的内存时会引发异常信号,虚拟机可通过内部的信号处理器捕获并停止Mutator线程的执行,这样一来相当于让所有Mutator线程主动停止。...根据上面的描述,安全点是一个全局的内存页,一旦VMThread开启安全点(将内存设置为不可读不可写)后,所有Mutator线程都会继续运行直到遇到附近的安全点读取,再通过异常处理机制主动停止。...但是有时并不需要停止所有Mutator线程,如偏向锁撤销,或者打印某个线程线程栈,在这些情况下,VMThread只需要停止某个指定的线程并打印线程栈即可。...GC屏障 GC屏障即后缀为BarrierSet的一系列类,它们的作用是在字段读操作或者写操作前后插入一段代码,执行某些垃圾回收必要的逻辑,如代码清单10-4所示: 代码清单10-4 GC屏障 public

    35230

    Go语言GC实现原理及源码分析

    Go 1.7 的时候选择的是将栈标记为恒灰,但需要在标记终止阶段 STW 时对这些栈进行重新扫描(re-scan)。..._GCoff GC 状态 改成 _GCmark,开启 Write Barrier (写入屏障)、mutator assists(协助线程),将根对象入队; 恢复程序执行,mark workers(标记进程...)和 mutator assists(协助线程)会开始并发标记内存中的对象。...工作线程以及 mutator assists(协助线程); 执行清理,如 flush mcache; the sweep phase(清理阶段) 将 GC 状态转变至 _GCoff,初始化清理状态并关闭...时间 0.009 ms:mutator assists占用的时间 0.40 ms:标记线程占用的时间 0.073 ms:idle mark workers占用的时间 0.16 ms:标记终止 STW 时间

    1.4K30

    GO进阶(5) 垃圾回收机制

    (Sweep)两个阶段标记阶段 — 从根对象出发查找并标记堆中所有存活的对象; 清除阶段 — 遍历堆中的全部对象,回收未被标记的垃圾对象并将回收的内存加入空闲链表; 主要流程: 进行STW(stop...the worl即暂停程序业务逻辑),然后从main函数开始找到不可达的内存占用和可达的内存占用 开始标记,程序找出可达内存占用并做标记 标记结束清除未标记的内存占用 结束STW停止暂停,让程序继续运行...2、三色标记法(go1.5垃圾回收原理) 1)为什么需要三色标记? 三色标记的目的,主要是利用Tracing GC做增量式垃圾回收,降低最大暂停时间。...三色标记增加了中间状态灰色,增量式GC运行过程中,应用线程的运行可能改变了对象引用树,只要让黑色对象直接引用白色对象,GC就可以增量式的运行,减少停顿时间。 2)、什么是三色标记?...对某些程序本身占用内存就低,容易触发 GC 对 API 接口耗时比较敏感的业务,如果  GOGC 置默认值的时候,也可能也会遇到接口的周期性的耗时波动。这是为什么呢?

    80131

    深度揭秘垃圾回收底层,这次让你彻底弄懂她

    而快照的获取需要停止 mutator 所有线程,不然就得不到一致的数据,导致一些活着对象丢失,这里说的一致性其实就像事务的一致性。...那 mutator 是如何得知此时需要在安全点暂停呢? 其实上面已经提到了是 check,再具体一些还分解释执行和编译执行时不同的 check。...标记-清除 分为两个阶段标记阶段:tracing 阶段,从根(栈、寄存器、全局变量等)开始遍历对象图,标记所遇到的每个对象。 清除阶段:扫描堆中的对象,将为标记的对象作为垃圾回收。...当 GC 结束之后灰色对象将全部没了,剩下黑色的为存活对象,白色的为垃圾。 一般增量式标记-清除会分为三个阶段: 根查找,需要暂停应用线程,找到根直接引用的对象。 标记阶段,和应用线程并发执行。...清除阶段。 这里解释下 GC 中两个名词的含义。 并发:应用线程GC 线程一起执行。并行:多个 GC 线程一起执行。 看起来好像三色标记没啥问题?来看看下图。 ?

    37920

    阿里高级专家推荐学习深入解析java虚拟机:垃圾回收,Parallel GC

    具体来说,GC线程执行完GCTask后不会简单停止,而是查看能否从其他线程任务队列中窃取一个任务队列,如果所有线程的任务队列都没有任务,再进入终结模式。...终结模式包含三个阶段,首先指定次数的自旋,接着GC线程调用操作系统的yield让出CPU时间,最后睡眠1ms。如果GC线程这三个小阶段期间发现有可窃取的任务,则立即退出终结模式,继续窃取任务并执行。...,几乎可以认为在垃圾回收进行时,Mutator也可以继续执行而无须暂停;并行是指垃圾回收过程中允许多个GC线程一同工作来完成某些任务,但是Mutator线程仍然需要暂停,即垃圾回收过程中应用程序需要一直暂停...Parallel GC为减少STW时间付出了努力,它的解决方式是暂停Mutator线程,使用多线程进行垃圾回收,最后唤醒所有Mutator,如图10-7所示。...但多线程并行化垃圾回收工作过程中Mutator线程仍然需要暂停,所以人们期待一种在垃圾回收阶段Mutator线程仍然能继续运行的垃圾回收器,或者至少在垃圾回收过程中大部分时间Mutator线程可以继续运行的垃圾回收器

    74530

    p7付费课程笔记6:CMS GC

    只有直接与GC Roots关联的对象才会被标记,降低初始标记的工作量。 初始标记后,CMS进入下一个并发标记阶段,应用线程GC线程并发执行。 起始标记阶段停止时间比较短,通常小于10ms。...情人节标记会重复多轮标记-Tracing process,知道对象所有的对象都被标记。 为控制标记进程,会设置标记周期,如果标记时间超过一定阈值则停止应用线程进行完整GC。...综上所述,CMS GC预清理阶段主要是初期阶段产生的浮动垃圾,减少下一阶段的工作量,从而达到大约停顿时间。 总结:此阶段同样是与应用线程并发执行的,不需要停止应用线程。...然后CMS进入清理阶段回收这些垃圾对象。 综上,最终标记停止所有应用线程进行的标记,它对并发标记做修改,准确描述标识所有不受影响的对象,为并发清理阶段做准备。...//翻译:CMS的第一阶段称为初始标记。这个阶段标记GC根(堆栈变量等)和可直接访问的对象。因为这个阶段mutator线程并发运行,所以它必须是保守的,以避免干扰正在运行的应用程序。

    23020

    JVM 系列(5)吊打面试官:说一下 Java 的四种引用类型

    阶段 1: 在垃圾收集的标记阶段,垃圾收集器会标记在本次垃圾收集中豁免的对象(包括强引用对象、FinalizerReference 对象以及不需要在本次回收的 SoftReference 软引用对象...先简单回顾下 CMS 并发标记清除算法分为 4 个阶段: 初始标记(暂停 mutator 线程): 仅仅标记GC Root 直接引用的对象,由于 GC Root 相对较少,这个过程相对比较短; 并发标记...(恢复 mutator 线程): 对初始标记得到的对象继续递归遍历,这个过程相对耗时。...由于此时 mutator 线程和 collector 线程是并发运行的,所以很可能会改变对象的可达性状态,因此这里会记录 mutator 线程所做的修改; 重标记(暂停 mutator 线程): 由于并发标记阶段可能会改变对象的可达性状态...但是并不是重新从 GC Root 递归遍历所有对象,而是会根据记录的修改行为缩小追踪范围,所以耗时相对比较短; 并发清理(恢复 mutator 线程): 标记工作完成后,进行释放内存操作,这个过程相对耗时

    56410

    safe-point(safepoint 安全点) 和 safe-region(安全区域)

    、它的寄存器文件以及一些线程上特定的数据 全局数据本身也是直接可达的 可达性分析为了确保能正确的决定对象是否存活,GC需要获取mutator 上下文的一致性快照,然后枚举所有的根对象。...safe-point有多个种类 GC safepoint,要触发一次GC,JVM中的所有线程都必须达到GC safepoint Deoptimization safepoint,要触发一次 deoptimization...由JIT负责把poll points放到合适的位置 那些地方适合设置检查GC事件的标记 polling point插入的主要原则是: polling point应该足够多,防止GC等一个mutator的暂停太长...当进入到safe-region中时,mutator会设置一个准备标记,在离开safe-region区域之前,会检查GC是否已经完成了回收,如果没有,那么就暂停执行,如果有,就可以直接离开safe-region...区域,不需要暂停mutator 总结 代码的执行过程中,如果需要执行某些操作,比如GC,deoptimize,等等,必须知道当前程序所有线程运行到的地方,是否能够恰好满足我执行对应操作,而不会对应用程序本身造成损害

    80310

    safe-point(safepoint 安全点) 和 safe-region(安全区域)「建议收藏」

    、它的寄存器文件以及一些线程上特定的数据 全局数据本身也是直接可达的 可达性分析为了确保能正确的决定对象是否存活,GC需要获取mutator 上下文的一致性快照,然后枚举所有的根对象。...safe-point有多个种类 GC safepoint,要触发一次GC,JVM中的所有线程都必须达到GC safepoint Deoptimization safepoint,要触发一次 deoptimization...,由JIT负责把poll points放到合适的位置 那些地方适合设置检查GC事件的标记 polling point插入的主要原则是: polling point应该足够多,防止GC等一个mutator...当进入到safe-region中时,mutator会设置一个准备标记,在离开safe-region区域之前,会检查GC是否已经完成了回收,如果没有,那么就暂停执行,如果有,就可以直接离开safe-region...区域,不需要暂停mutator 文章翻译自 Xiao-Feng Li 博客 rednaxelafx对safepoint的回答 总结 代码的执行过程中,如果需要执行某些操作,比如GC,deoptimize

    44020

    用了很多年的 CMS 垃圾收集器,终于换成了 G1,真香!!

    各个 Mutator 线程(即用户应用的线程)拥有各自的 Thread-Local Allocation Buffer (TLAB),用于降低各个线程分配内存的冲突。...为了尽可能降低对 Mutator 线程的影响,Write Barrier 的代码应当尽可能简化。...极端情况下,如果后台的 GC 进程追不上 Mutator 进程写入的速度,这时候 Mutator 线程会退化到自己处理更新,形成反压机制。...Mixed GC Mixed GC 的重要性不言而喻:Old Regions 的垃圾就是在这个阶段被收集掉的,也正是因为这样,Mixed GC 是工作量最为繁重的一个环节,如果不加以控制,就会像 CMS...如果只是对现场情况做标记,可能会漏掉某些对象 SATB 算法为了解决这一问题,在修改引用 X.f = B 之前插入了一个 Write Barrier,记录下被覆写之前的引用地址。

    99650

    五分钟技术小分享 - 2022Week12

    今天开始,我们将一起阅读下一篇内容,也就是官方博客对Go1.5版本GC的讲解。 原文链接 - https://go.dev/blog/go15gc 为什么我不选择最新版本进行讲解呢?...请跳转阅读 - https://go.dev/talks/2015/go-gc.pdf GC相关的差异(Go与Java) 维度 GO java 运行线程 1000+Goroutine 10+线程 同步机制...这一步,也就是初始化所有标记对象的集合。 Mark 标记 标记阶段即根据扫描出的初始指针对象,做BFS遍历,也就将所有可触达的对象加上标记。...这里有一句话: Write barrier tracks pointer changes by mutator. 也就是在标记阶段中,如果有程序变更了指针,就需要添加写屏障。...关于写屏障的实现细节我们先不细聊,先一起来看看GC中的三个概念: mutator:一般指应用程序,在运行过程中,会不停地修改堆对象里的指向关系 collector:垃圾回收期,更多地是指GC线程 allocator

    18620

    基础篇:java GC 总结,建议收藏

    需要 STW 并发标记:并发标记与初始化标记的对象有关联的所有对象,这类的对象比较多所以采用的并发,与用户线程一起跑 **并发预清理(Concurrent Preclean)**:并发标记阶段是与应用线程并发执行的...这块还涉及到对象的移动所以需要暂停所有的用户线程,多条回收器线程并行完成。需要 STW 为什么需要 Stop The World呢?...线程性能的影响,G1将一部分原本要在 write barrier 里做的逻辑分离出来交给异步线程并发执行:mutator 线程在写屏障里把分离的逻辑信息以 log 形式放到一个队列里,然异步线程再从队列里取出...后台异步线程会扫描,如果超过一定阈值就会处理,开始处理 10 CMS 常见问题 最终标记阶段停顿时间过长问题 CMS的GC停顿时间约80%都在最终标记阶段(Final Remark),若该阶段停顿时间过长...整体内存下导致晋升速率提高,老年区空间不足 存在大对象分配 CMS GC 发生 concurrent mode failure 时的 full GC 为什么是单线程的?

    45831

    可能是最全面的G1学习笔记

    初始标记(initial-mark),在这个阶段,应用会经历STW,通常初始标记阶段会跟一次新生代收集一起进行,换句话说——既然这两个阶段都需要暂停应用,G1 GC就重用了新生代收集来完成初始标记的工作...并发标记阶段(concurrent-mark),并发标记阶段是多线程的,我们可以通过-XX:ConcGCThreads来设置并发线程数,默认情况下,G1垃圾收集器会将这个线程总数设置为并行垃圾线程数(-...;ConcGCThreads指的是在并发标记阶段,并发执行标记线程数,一般设置为ParallelGCThreads的四分之一。 write barrier在GC中的作用?...write barrier在GC中的作用有点复杂,我们这里以trace GC算法为例讲下:trace GC有些算法是并发的,例如CMS和G1,即用户线程和垃圾收集线程可以同时运行,即mutator一边跑...;在并发标记周期的第二个阶段,并发标记,这是收集线程和应用线程同时进行的,这时候应用线程就可能修改了某些引用的值,导致上面那个快照不是完整的,因此G1就想了个办法,我把在这个期间对对象引用的修改都记录动作都记录下来

    96220

    最全面的G1学习笔记

    初始标记(initial-mark),在这个阶段,应用会经历STW,通常初始标记阶段会跟一次新生代收集一起进行,换句话说——既然这两个阶段都需要暂停应用,G1 GC就重用了新生代收集来完成初始标记的工作...并发标记阶段(concurrent-mark),并发标记阶段是多线程的,我们可以通过 -XX:ConcGCThreads来设置并发线程数,默认情况下,G1垃圾收集器会将这个线程总数设置为并行垃圾线程数(...;ConcGCThreads指的是在并发标记阶段,并发执行标记线程数,一般设置为ParallelGCThreads的四分之一。 write barrier在GC中的作用?...write barrier在GC中的作用有点复杂,我们这里以trace GC算法为例讲下:trace GC有些算法是并发的,例如CMS和G1,即用户线程和垃圾收集线程可以同时运行,即mutator一边跑...;在并发标记周期的第二个阶段,并发标记,这是收集线程和应用线程同时进行的,这时候应用线程就可能修改了某些引用的值,导致上面那个快照不是完整的,因此G1就想了个办法,我把在这个期间对对象引用的修改都记录动作都记录下来

    57300

    Golang源码探索----GC的实现原理(3)

    根对象 在GC标记阶段首先需要标记的就是"根对象", 从根对象开始可到达的所有对象都会被认为是存活的....标记队列 GC标记阶段会使用"标记队列"来确定所有可从根对象到达的对象都已标记, 上面提到的"灰色"的对象就是在标记队列中的对象....// 记录停止了多久, 和标记阶段开始的时间 now = nanotime() work.pauseNS += now - work.pauseStart...// 所有标记工作都会在世界已停止的状态执行 // (标记阶段会设置work.markrootDone=true, 如果跳过则它的值是false, 完成标记阶段会执行所有工作)...只扫描一次 // 并行GC中会在后台标记任务中扫描, 完成标记阶段(mark termination)中不扫描 // 非并行GC会在完成标记阶段(mark termination)中扫描

    1.1K10

    Java G1学习笔记

    1、初始标记(initial-mark),在这个阶段,应用会经历STW,通常初始标记阶段会跟一次新生代收集一起进行,换句话说——既然这两个阶段都需要暂停应用,G1 GC就重用了新生代收集来完成初始标记的工作...3、并发标记阶段(concurrent-mark),并发标记阶段是多线程的,我们可以通过-XX:ConcGCThreads来设置并发线程数,默认情况下,G1垃圾收集器会将这个线程总数设置为并行垃圾线程数...;ConcGCThreads指的是在并发标记阶段,并发执行标记线程数,一般设置为ParallelGCThreads的四分之一。 3、write barrier在GC中的作用?...write barrier在GC中的作用有点复杂,我们这里以trace GC算法为例讲下:trace GC有些算法是并发的,例如CMS和G1,即用户线程和垃圾收集线程可以同时运行,即mutator一边跑...;在并发标记周期的第二个阶段,并发标记,这是收集线程和应用线程同时进行的,这时候应用线程就可能修改了某些引用的值,导致上面那个快照不是完整的,因此G1就想了个办法,我把在这个期间对对象引用的修改都记录动作都记录下来

    1.1K10

    GC 的算法及收集器

    Mark-Sweep(标记-清除): 回收过程主要分为两个阶段,第一阶段为追踪(Tracing)阶段,即从 GC Root 开始遍历对象图,并标记(Mark)所遇到的每个对象,第二阶段为清除(Sweep...CMS收集器特点: ♣ 尽可能降低停顿 ♣ 会影响系统整体吞吐量和性能(用户线程运行过程中,分一半CPU去做GC,系统性能在GC阶段,反应速度就下降一半) ♣ 清理不彻底(因为在清理阶段,用户线程还在运行...,CMS收集器为什么使用标记清除算法而不是使用标记整理算法?...最终Eden空间的数据为空,GC停止工作,应用线程继续执行。 ?...Dump 线程、死锁检查、堆Dump 也会引起 Stop-The-World。 ☛ GC为什么会有全局停顿? 类比在聚会的时候打扫房间,只有让大家停止活动,才能打扫干净房间,否则会不断有新垃圾产生。

    42120
    领券