问题标签 [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.

0 投票
4 回答
5890 浏览

java - JVM CMS 垃圾收集问题

我在使用 Concurrent Mark-Sweep 收集器的应用程序的 GC 日志文件中看到以下症状:

预清洁过程不断中止。我尝试将 CMSMaxAbortablePrecleanTime 从默认值 5 调整为 15 秒,但这并没有帮助。当前的JVM选项如下...

似乎并发中止预清理永远没有机会运行。我阅读了https://blogs.oracle.com/jonthecollector/entry/did_you_know,其中建议启用 CMSScavengeBeforeRemark,但暂停的副作用似乎并不理想。有人可以提供任何建议吗?

另外我想知道是否有人对了解 CMS GC 日志有很好的参考,特别是这一行:

不清楚这些数字指的是哪些内存区域。 编辑 找到了这个http://www.sun.com/bigadmin/content/submitted/cms_gc_logs.jsp的链接

0 投票
4 回答
10007 浏览

java - Java ConcurrentMarkSweep 垃圾收集器未删除所有垃圾

简短形式:CMS 垃圾收集器似乎无法收集越来越多的垃圾;最终,我们的 JVM 被填满,应用程序变得无响应。通过外部工具(JConsole 或jmap -histo:live)强制 GC 将其清理一次。

更新:问题似乎与 JConsole 的 JTop 插件有关;如果我们不运行 JConsole,或者在没有 JTop 插件的情况下运行它,行为就会消失。

(技术说明:我们在 Linux 2.6.9 机器上运行 Sun JDK 1.6.0_07,32 位。升级 JDK 版本并不是一个真正的选择,除非有不可避免的主要原因。此外,我们的系统不是连接到可访问 Internet 的机器,因此不能选择 JConsole 的屏幕截图等。)

我们目前正在使用以下标志运行我们的 JVM:

观察 JConsole 中的内存图,在我们应用程序生命周期的前几个小时内,每 15 分钟左右运行一次完整的 GC;在每次完全 GC 之后,仍然有越来越多的内存在使用中。几个小时后,系统进入稳定状态,在 CMS 老一代中大约有 2GB 的已用内存。

这听起来像是典型的内存泄漏,除了如果我们使用任何强制执行完整 GC 的工具(点击 JConsole 中的“收集垃圾”按钮,或运行jmap -histo:live等),老一代突然下降到使用约 500MB,而我们的应用程序在接下来的几个小时内再次变得响应(在此期间相同的模式继续 - 在每次完整 GC 之后,越来越多的老一代已满。)

需要注意的一点:在 JConsole 中,报告的 ConcurrentMarkSweep GC 计数将保持为 0,直到我们使用 jconsole/jmap/etc 强制进行 GC。

依次使用jmap -histojmap -histo:live,我能够确定明显未收集的对象包括:

  • 数百万HashMaps 和数组HashMap$Entry(以 1:1 的比例)
  • 几百万Vector个s和Object数组(1:1的比例,和HashMap的个数差不多)
  • 几百万个HashSet, Hashtable, 和com.sun.jmx.remote.util.OrderClassLoaders,以及数组Hashtable$Entry(每个的数量大致相同;大约是 HashMap 和向量的一半)

下面是 GC 输出的一些摘录;我对它们的解释似乎是 CMS GC 在没有故障转移到 stop-the-world GC 的情况下中止。我是否以某种方式误解了这个输出?有什么会导致这种情况吗?

在正常运行时,CMS GC 输出块如下所示:

就是这样;下一行将是下一个 ParNew GC。

当我们使用 jmap -histo:live 强制 GC 时,我们会得到:

然后是下面表格的约 125 行:(一些 GeneratedMethodAccessor、一些 GeneratedSerializationConstructorAccessor、一些 GeneratedConstructorAccessor 等)

其次是:

提前致谢!

0 投票
2 回答
532 浏览

java - 有没有办法通过 JMX 识别 CMS 并发模式故障?

因此,我一直在尝试寻找一种好方法来监控 JVM 何时可能会出现 OOM 情况。他们似乎与我们的应用程序一起工作的最佳方式是通过 CMS 跟踪背靠背并发模式故障。这表明永久池的填充速度超过了它实际清理自身的速度,或者它的回收速度非常慢。

用于跟踪 GC 的 JMX bean 具有非常通用的信息,例如之前/之后的内存使用情况等。这些信息充其量是相对不一致的。有没有更好的方法可以监控这个即将死去的 JVM 的潜在警告信号?

0 投票
1 回答
679 浏览

performance - 如何记录和绘制 Java 应用程序的对象生命周期?

我们想为我们的 Java 应用程序调整内存生成池的大小。为此,我们首先需要了解堆是如何使用的。本质上,我们需要知道 JVM 堆中每个对象的数量、大小和生命周期。在我们收集了这些数据之后,我们应该能够找到更适合我们的年轻代和终身代池的规模。

我们的调优工作基于 Sun/Oracle 的“使用 5.0 JVM 调优垃圾收集”白皮书中的信息。在第 3 节(http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html#1.1.%20Generations%7Coutline)中,他们讨论了生成大小并在对象生命周期图上展示了一个示例。几乎是我们试​​图为我们的应用程序实现的目标。

到目前为止,我们已经能够记录给定类的实例数量以及它们在内存中各自的大小。但是我无法找到一种方法来提取平均实例寿命。现在我们正在研究 jProfiler,但到目前为止还没有成功。

有没有人成功地绘制了 Java 应用程序的平均对象生命周期?

0 投票
4 回答
3015 浏览

java - Java ConcurrentMarkSweep 垃圾收集器没有发生

环境详细信息:操作系统:Linux RedHat Java:JRE 6 Update 21

我正在为我的应用程序使用以下 GC 设置。

有了那里的设置,在应用程序开始时会有一个 Full GC

随后是 4-5 次成功的 CMS 收集,但在此之后日志中没有 CMS 的痕迹,只有次要收集上有条目。

堆不断增长,已达到 7GB。我们必须重新启动应用程序,因为我们无法承受 OOM 或生产系统中的任何故障。

我不明白为什么 CMS 收集器停止清理。欢迎任何线索/建议。提前致谢。

==================================================== =====================================1月23日更新。

感谢大家到现在为止的回复。我已经在测试环境中设置了应用程序并使用以下一组 JVM 选项测试了该应用程序:

选项1

选项 #2

我用两种设置并行运行了 2 天的测试。这些是我的观察:

选项 #1 堆内存稳定,但有 90 个 ConcurrentMarkSweep 集合,JVM 花费了 24 分钟。那太高了。我在 GC 日志中看到以下几行,并且模式每隔一小时继续一次......

我没有看到并发标记和扫描日志。这是否意味着 CMS 切换到吞吐量收集器?如果是,为什么?

选项#2:

由于我看到了 Full GC (System) 日志,所以我想到了添加 -XX\:+DisableExplicitGC。但是使用该选项不会发生收集,当前堆大小为 7.5G。我想知道为什么 CMS 正在执行 Full GC 而不是并发收集。

0 投票
4 回答
66139 浏览

java - UseConcMarkSweepGC 与 UseParallelGC

我目前遇到垃圾收集时间很长的问题。请参阅以下内容。我当前的设置是我正在使用 -Xms1g 和 -Xmx3g。我的应用程序使用的是 java 1.4.2。我没有设置任何垃圾收集标志。从外观上看,3gb 是不够的,我真的有很多对象要垃圾收集。

问题:

我应该改变我的垃圾收集算法吗?我应该用什么?是不是更好用-XX:+UseParallelGC or -XX:+UseConcMarkSweepGC

还是我应该使用这种组合

占用内存的主要是报告数据,而不是缓存数据。另外,机器有 16gb 内存,我计划将堆增加到 8gb。

这两个选项之间有什么区别,因为我仍然很难理解。机器有多个处理器。我最多可以承受 5 秒的打击,但 30 到 70 秒真的很难。

谢谢您的帮助。

0 投票
1 回答
19183 浏览

java - CMS 垃圾收集器 - 它何时运行?

我对可能控制 CMS 收集器何时启动的两个参数感到困惑:

MaxHeapFreeRatio(默认为 70%)

CMSInitiatingOccupancyFraction(默认超过 90%)

这些参数中的每一个到底是什么意思?收集器何时开始(标记阶段)和收集(清扫阶段)?

0 投票
1 回答
1020 浏览

java - Java GC CMS 收集器时间

我们为我们的应用程序启用了垃圾收集日志。我看到一些行,它打印了一些 CMS 步骤的时间。任何人都可以解释或指向一些解释 CMS 日志的链接,例如

9657.238:[CMS 并发标记:17.199/17.396 秒] [时间:用户 = 80.61 系统 = 10.00,实际 = 17.40 秒]

0 投票
2 回答
5384 浏览

java - 使用大于 120GB RAM 的并发标记清除垃圾收集器

有没有人设法在具有超过 120GB RAM 的热点中使用并发标记扫描垃圾收集器 (UseConcMarkSweepGC)?

如果我将 -ms 和 -mx 设置为 120G,则 JVM 可以正常启动,但如果我将它们设置为 130G,则 JVM 在启动时会崩溃。JVM 在并行收集器和 G1 收集器上启动良好(但它们有自己的问题)。

有没有人设法使用超过 120GB 堆的并发标记扫描收集器?如果是这样,您是否需要做一些特别的事情,或者我只是在这里不走运?

来自 JVM 错误转储的堆栈如下:

我已经用 Oracle ( http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7175901 )提出了一个错误,但我想知道是否有其他人看过它。

0 投票
2 回答
1612 浏览

java - 并发标记扫描收集发生的频率不够

我的应用程序在具有 16 个处理器和 64 GB 内存的服务器上正确运行。我有多个进程,我尝试将我的进程的最大堆限制为 8 GB。

我的问题是我有某种形式的生产者-消费者模式,我必须限制生产速率,否则我会耗尽内存,因为老年代的垃圾收集发生得太少了。

  • 当我监控我的应用程序时,我可以看到运行 4 小时后,我在 ParNEW 中花费了 7 分钟,在 ConcurrentMarkSweep 中花费了 0.775 秒。
  • 我的堆占用上升到大约 6GB,然后下降到 1GB,然后慢慢开始上升到 6GB,然后再次下降。周期约为 10 分钟

通过 JVisualVM 我可以看到 90% 的内存占用是由 CMS Old Gen 给定的,如何强制并发标记扫描运行得更频繁一些?


@PeterLawrey 评论非常相关,因为我的应用程序运行在应用程序服务器的顶部,该应用程序服务器专为事件驱动处理和数据分区而设计,例如 Terracotta 或 Coherence。底层实现很可能包括用于事件处理的排队系统。

我的问题是限制堆大小不是解决方案,因为正如我所经历的那样,应用程序没有更频繁地进行垃圾收集,而是耗尽了内存。