问题标签 [concurrent-mark-sweep]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 为什么 JVM 一直在做 full gc 而老年代只有半满?
我在 CentOS 64 位 linux 机器上使用 jdk 1.7.0_09。
gc 相关的 vm args 是
-Xmx4g -Xmn2g -XX:SurvivorRatio=4 -XX:PermSize=128m -XX:MaxPermSize=128m -XX:InitialTenuringThreshold=15 -XX:CMSWaitDuration=50 -XX:MaxTenuringThreshold=15 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=80 -XX:+CMSParallelRemarkEnabled -XX:ReservedCodeCacheSize=128m
但它一直在做完整的 gc
java - 可以假设 Java Concurrent Mark Sweep Garbage Collector 在 Linux 和 Mac 以及 Windows 上同样出色吗?
我一直在网上寻找有关使用 Java Concurrent Mark Sweep GC for Linux 和 Mac 或不同版本的 Java 的信息。我对 Oracle Java 1.6 和 1.7 的最新版本特别感兴趣。
我会假设它可以运行,因为我没有发现任何相反的东西,但是与 Windows 相比,包括 OpenJDK 在内的性能有什么明显的差异吗?
java - Why JVM CMS(concurrent mark-and-sweep) needs two pauses for GC?
I wonder why CMS needs two phases (and so two pauses) of marks: i.e. initial mark and remark. Can we simply do one mark and then perform sweep? I imagine this can be a faster pause. Can someone help explain what is the main purpose of the second mark and why we need it? Thanks!
java - -XX:+UseConcMarkSweepGC(什么是默认的年轻代收集器?)
据我所知,我们可以使用以下选项运行 JVM:
在这种情况下,我们将为年轻代使用Serial (DefNew)垃圾收集器,为老年代使用Concurrent Mark Sweep垃圾收集器。
那么,我们可以-XX:+UseConcMarkSweepGC
仅使用选项运行 JVM 吗?我的意思是没有任何描述年轻一代垃圾收集器的选项。如果我们能做到这一点,那么老年代将使用哪个垃圾收集器?
java - 为什么 CMS 收集器会在 Initial Mark 阶段从年轻代收集根引用?
据我所知,CMS 收集器收集老年代,它与 ParNew 收集器(用于收集年轻代)一起工作。对我来说,要清楚地理解 CMS 的工作原理并不容易,但这是我的看法:
1) 初始标记。寻找根参考。由于收集器是 oldgen 收集器,它应该只扫描老年代。
2) Concurrent-Mark 找到所有根引用后,就该开始并发标记了。从第一阶段标记的对象可传递到达的所有对象都在该阶段标记。
3) 并发预清理 gc 查看 CMS 堆中的对象,这些对象在我们在前一个并发标记阶段进行并发标记时由年轻代的提升或新分配更新或由突变器更新。[请确认1 这个阶段的唯一目的是完成下一个阶段必须完成的部分工作(备注)?2) 有一些进程正在查看在并发标记阶段更改了哪些引用。请告诉我我对这两个项目是否正确]
4) 备注 gc 停止世界,然后查看 CMS 堆中的对象,这些对象在我们进行并发预清理时由年轻代的提升或新分配更新或由 mutators 更新。
但是今天看到这篇文章
初始标记在初始标记期间,CMS 应收集所有根引用以开始标记旧空间。这包括:来自线程堆栈的引用、来自年轻空间的引用。来自堆栈的引用通常被收集得非常快(小于 1ms),但是从年轻空间收集引用的时间取决于年轻空间中对象的大小。通常初始标记在年轻空间收集后立即开始,因此伊甸园空间是空的,只有存活对象位于幸存者空间之一。幸存者空间通常很小,年轻空间收集后的初始标记通常需要不到毫秒的时间。但是,如果在 Eden 已满时开始初始标记,则可能需要很长时间(通常比年轻空间收集本身更长)。一旦触发了 CMS 收集,JVM 可能会等待一段时间让年轻收集发生,然后才会开始初始标记。JVM 配置选项 –XX:CMSWaitDuration= 可用于设置 CMS 在开始初始标记之前等待年轻空间收集的时间。如果您想避免长时间的初始标记暂停,您应该将此时间配置为比应用程序中年轻集合的典型周期更长。
备注大部分标记与应用程序并行完成,但可能不准确,因为应用程序可能会在标记期间修改对象图。并发标记完成时;垃圾收集器应该停止应用程序并重复标记,以确保所有可到达的对象都标记为活动的。但是收集器不必遍历整个对象图;它应该只遍历自标记开始以来修改的参考(实际上是自开始预清洁阶段以来)。卡片表(参见卡片标记写屏障)用于识别旧空间中内存的修改部分,但应再次扫描线程堆栈和年轻空间。 通常remark阶段的大部分时间都花在扫描年轻空间上。如果我们在评论开始之前在年轻空间中收集垃圾,这个时间会短得多。我们可以指示 JVM 在 CMS 备注之前始终强制进行年轻空间收集。使用 JVM 参数 –XX:+CMSScavengeBeforeRemark 启用此选项。即使年轻空间是空的,remark 阶段仍然需要扫描 old space 中的修改引用,这通常需要接近正常年轻收集暂停的时间(由于在年轻收集期间完成的 old space 扫描类似于 remark 所需的扫描)。
http://blog.griddynamics.com/2011/06/understanding-gc-pauses-in-jvm-hotspots_02.html
不明白为什么 CMS 需要扫描年轻代。为什么老年代垃圾回收需要它?
java - Java 1.6 和 1.7 之间的 Conc Mark 和 Sweep Garbage Collector 区别
我在 CMS GC 中使用 jdk 1.6,当我尝试迁移到 JDK 1.7 时,堆使用量增加并且进程变慢。
这些版本中的 GC 行为是否存在重大差异?如果它在 JDK 1.7 中变慢了,解决方法是什么?
java - Concurrent Mark Sweep (CMS) 是一项停止世界活动吗?
我看到许多卸载类,我的整个系统将在那段时间挂起..
同时我没有看到烫发空间的峰值,所以它似乎不是 GC 事件。
我想知道以下
Concurrent Mark Sweep 收集是停止世界事件吗?
即使烫发空间未满,也会发生这种情况吗?
java - 并发标记清除 (CMS) 卸载类中的对象类
通常对于 CMS,我会看到以下标准输出
[卸载类 sun.reflect.GeneratedMethodAccessorXXX] [卸载类 sun.reflect.GeneratedConstructorAccessorXXXX] [卸载类 sun.reflect.GeneratedSerializationConstructorAccessorXXX] [卸载类 sun.reflect.GeneratedSerializationConstructorAccessorXXX] [卸载类 sun.reflect.GeneratedSerializationConstructorAccessorXXX]
但我也注意到其中的以下内容
[卸载类 Customer_datasetXXXXX] – 日志中出现 280+
[卸载类 Item_XXXXXX] – 日志中出现 220+
[卸载类 Receipt_XXXXX] – 日志中出现 30+
[卸载类 Foo_XXXXX] – 日志中出现 190 次
*XXXXX 只是随机数。
我可以知道什么最有可能导致上述情况,这是否正常?
我不明白为什么类对象会出现那么多?类是模板,对象是类的实例。那么为什么我有这么多的 Foo 类被卸载呢?
java - Java CMS GC,GC线程在系统空闲时占用CPU
我们在 tomcat 7、JDK 7、Amazon Linux 中有一个 Web 应用程序。这就是我们的 GC 配置:
我们没有启用“PrintGCDetails”。
这是每隔几秒钟在 gc.log 文件中打印的内容(当此时应用程序处于 0 负载下时,连续 48 小时 - 绝对没有活动,即使这样,以下内容也会被打印出来,并且这些线程占用的 CPU 是15%)(请参阅下文了解上下文):
我们看到以下 GC 线程占用了 CPU(总共大约 15%),即使:
- 系统中没有活动,
- 除了这些之外,没有其他线程处于活动状态,这会持续 48 小时,此时系统处于 0 负载之下。
- 系统在前 24 小时内也处于 0 负载下,然后这些线程变为活动状态
- 当这些线程处于活动状态并占用 CPU 时,前面的行会打印在 gc.log 中
- 这种情况持续了 2 天,当我们最终通过在这个 JVM 中调用 Web 应用程序 5 分钟来加载负载时,一切都停止了。我们注意到这些线程现在不再占用 CPU(它们占用了 <1 %)。一旦 FULL GC 发生,问题似乎已经自行解决。FULL GC 发生在系统加载后。
- 简而言之,当系统处于 0 负载 48 小时时,GC 线程继续占用 15% 的 CPU。
这些是线程:
问题 1:为什么这些线程占用 15% CPU 时 gc 日志会填满以下内容?
问题2:上面的日志是否表明CMS(标记、扫描等)失败?
问题 3:为什么当我们在 Web 应用程序上引入中等负载并发生 FULL GC 时它会自行解决?
是的,我将尝试在启用 printGCDetails 的另一个环境中复制该问题并返回信息或解决方案 - 如果有人之前看到过,请添加到对话中。
编辑1:这是启用“PrintGCDetails”时的日志:
另请注意:“CMSMaxAbortablePrecleanTime”设置为 35 秒。谢谢。
java - 连续 CMS 收集,随后出现并发模式故障
我的 Java 应用程序的 GC 日志显示连续的 CMS GC,然后是并发模式失败的 stop-the-world 收集,该收集几乎回收了整个堆。
为什么 CMS 集合无法清除老年代?为什么需要并发模式故障停止世界收集?
像下面这样的 CMS 收集连续发生了几天,然后并发模式故障最终迫使一个清理空间的 stop-the-world 收集。请注意 CMS 集合如何恢复几乎没有空间,而升级失败后的集合将老年代从 1.92 GB 减少到 50.7 MB。
老年代对象是否由永久代中已死的、未收集的对象保持活力,这些对象在 STW 收集期间被丢弃?我应该考虑使用 -XX:+CMSClassUnloadingEnabled 来解决这个问题吗?
在 GC 日志中完成 CMS 收集:
并发模式失败GC日志:
Java版本:
JVM 选项: