gpt4 book ai didi

java - 为什么 CMS 收集器在 Initial Mark 阶段从年轻代收集根引用?

转载 作者:行者123 更新时间:2023-11-30 07:11:56 27 4
gpt4 key购买 nike

据我所知,CMS 收集器收集老年代,它与 ParNew 收集器(用于收集年轻代)一起工作。清楚地了解 CMS 的工作原理对我来说并不容易,但我是这样看的:

1) 初始标记。寻找根引用。由于收集器是老年代收集器,它应该只扫描老年代。

2) 并发标记找到所有根引用后,就该开始并发标记了。从第一阶段标记的对象传递可达的所有对象都在这一阶段标记。

3) 并发预清理gc 查看 CMS 堆中的对象,这些对象是通过年轻代或新分配的提升而更新的,或者是在我们在前一个并发标记阶段进行并发标记时被 mutators 更新的。 [请确认 1 这个阶段的唯一目的是完成下一阶段必须完成的部分工作(备注)? 2)有一些进程正在查看在并发标记阶段更改了哪些引用。 请告诉我我对这两项的看法是否正确]

4) 备注gc 停止世界,然后查看 CMS 堆中的对象,这些对象在我们进行并发预清理时通过年轻代或新分配的提升或由 mutators 更新。

但是今天看到这篇文章

Initial mark During initial mark CMS should collect all root references to start marking of old space. This includes: References from thread stacks, References from young space. References from stacks are usually collected very quickly (less than 1ms), but time to collect references from young space depends on size of objects in young space. Normally initial mark starts right after young space collection, so Eden space is empty and only live objects are in one of survivor space. Survivor space is usually small and initial mark after young space collection often takes less than millisecond. But if initial mark is started when Eden is full it may take quite long (usually longer than young space collection itself). Once CMS collection is triggered, JVM may wait some time for young collection to happen before it will start initial marking. JVM configuration option –XX:CMSWaitDuration= can be used to set how long CMS will wait for young space collection before start of initial marking. If you want to avoid long initial marking pauses, you should configure this time to be longer than typical period of young collections in your application.

Remark Most of marking is done in parallel with application, but it may not be accurate because application may modify object graph during marking. When concurrent marking is finished; garbage collector should stop application and repeat marking to be sure that all reachable objects marked as alive. But collector doesn’t have to traverse through whole object graph; it should traverse only reference modified since start of marking (actually since start pre clean phase). Card table (see card marking write barrier) is used to identify modified portions of memory in old space, but thread stacks and young space should be scanned once again. Usually most time of remark phase is spent of scanning young space. This time will be much shorter if we collect garbage in young space before starting of remark. We can instruct JVM to always force young space collection before CMS remark. Use JVM parameter –XX:+CMSScavengeBeforeRemark to enable this option. Even is young space is empty, remark phase still have to scan through modified references in old space, this usually takes time close to normal young collection pause (due scanning of old space done during young collection is similar to scanning required for remark).

http://blog.griddynamics.com/2011/06/understanding-gc-pauses-in-jvm-hotspots_02.html

不明白为什么CMS需要扫描新生代。为什么老年代垃圾回收需要它?

最佳答案

你可能有循环引用的类,比如类 A 引用了类 B,B 有一个对 A 的反向引用。如果你有属于这些类的对象 a 和 b,并且相互引用,gc当您从“外部”删除对它们的最后引用时,必须删除它们。当然,如果引用循环包含更多元素,情况可能会复杂得多。因此 gc 必须检查哪些元素可以从某个根访问,哪些元素被引用但不可访问,并且应该被收集。

现在,如果你有,在你的代码中的某处

Object a=new A(new B(new C(new D())))

在分配 a 之前,构造函数可能需要一些时间。但是你不希望 gc 删除新创建的 D,只是因为 C 的构造函数需要一段时间才能运行,而 a 还没有被分配。因此,您还需要扫描新生代,以捕获太年轻而无法从堆中引用的对象。

关于java - 为什么 CMS 收集器在 Initial Mark 阶段从年轻代收集根引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20709033/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com