问题标签 [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 - -XX+UseCMSCompactAtFullCollection 的确切用途是什么?
我知道它告诉 CMS 收集器在发生完整 GC 时对旧代进行压缩。
但我想确认我是否理解正确(从各种来源拼凑而成):
完整的 GC 会暂停世界,收集并压缩旧代(使用 CMS 的备注阶段的结果),然后收集年轻代,提升对象(如果有的话),然后恢复世界。
此时,old gen 中可能有浮动垃圾,UseCMSCompactAtFullCollection
就是清理它们并再次压缩 old gen(基本上是 old gen 上的另一个 GC)。因为无论如何世界都停止了,所以做更多的压缩可能是值得的。
这个描述正确吗?我错过了任何重要的细节吗?谢谢
jboss - CMS-concurrent-preclean abort 是否会导致耗时的 CMS-concurrent-sweep 执行?
java版本
java 版本 "1.6.0_21" Java(TM) SE Runtime Environment (build 1.6.0_21-b07) Java HotSpot(TM) 64-Bit Server VM (build 17.0-b17, 混合模式)
jvm配置:
-server -XX:+DoEscapeAnalysis -XX:+CMSParallelRemarkEnabled -XX:+UseBiasedLocking -XX:ParallelGCThreads=20 -XX:+UseLargePages -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSConcurrentMTEnabled -XX:SurvivorRatio=8 - XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=15 -XX:ReservedCodeCacheSize=128m -XX:+UseCodeCacheFlushing -XX:NewRatio=3 -XX:+DisableExplicitGC -Dsun.rmi.dgc.client.gcInterval=1800000 -Dsun.rmi。 dgc.server.gcInterval=1800000 -Djava.net.preferIPv4Stack=true -Xss1024k -Xms8192m -Xmx8192m -XX:MaxPermSize=1024m -XX:PermSize=1024m -Dremoting.bind_by_host=false -Dorg.jboss.resolver.warning=true - Dclient.encoding.override=UTF-8 -Dfile.encoding=UTF-8 -Dnet.sf.ehcache.skipUpdateCheck=true -Dorg.apache.xerces.xni.parser.XMLParserConfiguration=org.apache.xerces。parser.XIncludeAwareParserConfiguration
-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true -Dorg.apache。 el.parser.COERCE_TO_ZERO=false -Dorg.apache.catalina.connector.Request.SESSION_ID_CHECK=false
CMS-concurrent-preclean abort 是否会导致耗时的 CMS-concurrent-sweep 执行?会不会给用户造成 48 秒的世界停止体验?从上面的 gc 日志推断是什么。
java - 什么时候有人会在多核机器上使用带有 CMS 垃圾收集器的单线程?
我正在使用 Java 7 JVM 的服务器上运行 Apache Storm 拓扑。我一直在考虑对 JVM 进行一些调整,并注意到它当前正在使用并发标记和清除 (CMS) 垃圾收集器。这是有道理的,因为服务器有 32 个内核,并且在使用此设置运行多个 JVM 时,它只运行了 4 个少于 32 个内核的此类 JVM。
但是,我注意到我们在设置CMSConcurrentMTEnabled
关闭的情况下运行垃圾收集器。默认设置是打开的,这让我想知道为什么有人会在其他线程可用时选择使用单个线程进行并发垃圾收集。假设其他线程可用,在什么条件下使用该设置有意义?
(编辑以获取有关我当前情况的更多详细信息,希望它会导致答案):
JVM 似乎内存不足,反复执行次要 GC,每次大约需要 9 秒,最终崩溃。没有OutOfMemoryError
被抛出,这让我感到困惑。次要 GC 每次都会清理几个 kB,并且总体使用量在 100% 左右徘徊了很长一段时间。堆大小为 4 GB,因此这些条件应触发OutOfMemoryError
. 但是,我担心,对于一个 SO 问题,这将进入一个非常本地化的情况。
java - Java 垃圾收集器分配失败
我在具有 8GB 内存和 4 个 CPU 的机器上运行我的 java 应用程序。但是在通过压力测试运行应用程序较长时间后,观察到垃圾收集器问题,因为内存已完全满,并且似乎 gc 循环需要更长的时间才能完成,但我无法找出可能的原因及其解决方案。我们完成请求的平均延迟没有太大差异。但它不能同时服务很多线程。
我已经使用以下参数开始了我的应用程序
top 命令的输出
填充内存后的示例 GC 日志
我想得出结论,为什么内存这么多,以及我可以做些什么来克服它,以便我可以在更高负载的情况下长期运行我的应用程序。请帮我这样做。
java - CMS 垃圾收集耗时过长
我们的一位客户遇到了主要的性能问题,这似乎是由长时间的垃圾收集运行引起的,我不知道该怎么办......
Java 版本:1.7.0_67 JVM 参数:-Xms10240m -Xmx16386m -XX:NewSize=2048m -XX:MaxPermSize=150m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails ...
附加信息
该应用程序是我们的 Web 应用程序的服务器后端。服务器连接到一个 SQL 数据库和多个 ERP 系统。然后处理此数据并将其发送到 Web 客户端。尤其是该客户在全球拥有大约 50 个用户,他们通过这台服务器访问数据。
- 操作系统:Windows Server 2008 R2 数据中心 + SP1
- CPU:至强 E5-2660(4 核 + HT)
- 内存:32 GB
到目前为止我尝试过的
- 增加 Xmx 和 Xms(读取 Xms 应该相同或至少接近 Xmx 以获得最佳性能)
- 调整年轻代的大小(比率 1、2、3)
- 增加 PermGeneration
- 尝试了不同的 GC 变体
这是 gc 日志的一些部分。您可以清楚地看到 gc 持续时间随着时间的推移而增加,并在大约 !!!17 秒 !!! 处达到峰值。
什么可能导致这些问题?是否有任何需要修补的 JVM 参数?
更新 / 25.03.2016
在让 VisualVM 运行之后,我似乎发现了其中一个问题:Young Generation 现在设置为 4GB - Eden 和 Survivor 之间的比率似乎很遥远...... Eden = 3,5 GB 而 Survivor = 0,5 GB As一直在生成很多新对象(我必须进一步调查),伊甸园的填充量超过 0.5 GB(更像是 1 到 2 GB)。Survivor 无法持有它,因此触发了 Major GC。
出现的新问题:
- 我的假设错了吗?
- 我认为我的下一步应该是手动设置幸存者比率。根据我的情况有什么建议吗?
- 我需要禁用 AdaptiveSizePolicy 吗?(-XX:-UseAdaptiveSizePolicy)
- 为什么GC日志显示原因为“System.gc()”,而代码中肯定没有触发手动GC(反编译所有类并检查):
2016-03-25T04:59:55.726+0100: 14992.418: [Full GC (System.gc())2016-03-25T04:59:55.726+0100: 14992.418: [CMS: 265708K->265749K(6291456K), 1.1520720 secs] 507160K->265749K(10066368K), [CMS Perm : 54875K->54875K(91504K)], 1.1523255 secs] [Times: user=1.14 sys=0.00, real=1.14 secs]
旧日志 / 24.03.2016
启动后的前几个日志:
一段时间以后:
在 gc 持续时间的峰值:
完整日志: http: //pastebin.ca/3409912
java - G1 和 CMS 的 UseCompressedOops 启动阈值不同
我正在运行 Oracle 的 64 位 Java 1.8 Hotspot JVM。当使用不同的 GC 机制时,我一直试图围绕 JVM 的行为差异来启动压缩对象指针。例如:
我已尝试更改其他一些 G1GC 旋钮,但无法获得压缩指针优化以启动 G1 超过 32736 MB 的堆大小。但是,您可以清楚地看到,CMS 可以将压缩指针用于高达 32766 MB 的堆大小。我试图了解是什么控制了不同 GC 算法的这个阈值。
java - 为什么CMS全GC是单线程的?
每当使用 CMS 出现并发模式失败或升级失败时,它都会使用单线程进行完整 GC。为什么它不能使用并行收集器进行完整 GC 以减少完整 GC 惩罚?
java - 为什么 CMS 是为初始标记停止世界,而不是为扫荡阶段?
CMS 有 4 个高级阶段适用于完整的 GC
- 初始标记:- 停止世界(STW)
- 并发标记:-同时运行
- 备注 :- STW
- 并发扫描:- 并发运行
阅读后我对CMS有了高度的了解
http://www.tikalk.com/java/garbage-collection-serial-vs-parallel-vs-concurrent-mark-sweep/和https://plumbr.eu/handbook/garbage-collection-algorithms-implementations/concurrent -标记和扫描
我的问题是为什么初始标记阶段是 STWInitial Mark
阶段?我们不能将 Remark 阶段设置为 STW,因为这是和解的最后阶段。
同样,为什么Sweeping phase
不是 STW,因为它需要压缩,这意味着对象的物理位置的变化。因此,如果应用程序引用了对象并且并发线程更改了物理位置,那不是问题吗?
我知道我在这里遗漏了一些东西,但那是什么?
java - 即使老一代/年轻一代有足够的空间,CMS 终身阶段的频率也很高
我预先承认这个问题非常类似于: high-number-of-cms-mark/remark-pauses-even-though-old-gen-is-not-half-full and tenured-collection-starting-for-没有明显的原因。我发帖是因为 1. 这些线程已经超过 1 年了,并且 2. 我希望学习如何找到导致这种行为发作的根本原因。
我们有一个 OAS/OC4J (这不是我们的错!)在 RHEL5/Redhat 5.11、Java 6 上运行的 24/7 Java 应用程序服务器。这在内存方面已经稳定了很多年,直到最近我们开始看到高 CPU 利用率,因为频繁的 CMS 终身空间周期。即使在年轻和长期空间中都有足够的空间时,也会发生这种情况。我对这个主题的阅读表明,CMS 终身循环通常在终身(老一代)空间大约占容量的 92% 时开始。但是我们看到这种情况反复发生,而容量甚至更少。而且,我应该提一下,当总堆似乎小于整体堆使用的默认值 45% 时,也就是InitiatingHeapOccupancyPercent
.
我们仍在审查最近的代码更改并尝试了一些事情,但这些问题仍然存在。所以,到目前为止,我们无法在生产服务器之外进行复制,尽管在开发/质量保证环境中的努力正在进行中。
我想我在这里有三个主要问题:
- 什么可能会触发 CMS 周期的频繁(过早?)初始标记阶段。而且,我们如何验证或调查这一点?例如,检查当前内存分配的各个部分(伊甸园、幸存者、老一代)是否有巨大的对象等?
- 我已经阅读了有关使用
-XX:+UseCMSInitiatingOccupancyOnly
and的内容-XX:CMSInitiatingOccupancyFraction=NN
(例如在上面引用的文章中)。什么可能是 NN 的合理(== 安全)值,以这种方式覆盖默认 CMS 人体工程学的风险是什么? - 我们应该考虑或调查其他任何事情吗?
以下是有关我们问题的一些详细信息:
- 所以,到目前为止,我们无法在生产之外重现这一点。因此,调试或调整不是一种选择
- 我们使用每晚的 cron 作业来强制 Full GC 通过jmap -histo:live pid减少碎片
- 我们的 JVM 命令行参数 wrt 内存如下:
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintTenuringDistribution
-XX:-TraceClassUnloading
-XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExplicitGCInvokesConcurrent
-XX:+UseCMSCompactAtFullCollection
-Xms10g
-Xmx10g
-Xmn3g
-XX:SurvivorRatio=6
-XX:PermSize=256m
-XX:MaxPermSize=256m
-XX:TargetSurvivorRatio=80
-XX:ParallelGCThreads=8
注意:我们最近尝试将年轻代提升到 3.5g,这是一个有点绝望的实验。(在生产中!)没有观察到真正可辨别的差异
- 的输出
jmap -heap
。注意:From Space
似乎总是 100% 被占用。这是正常的,还是预示着什么?:
- 内部 GC 日志解析器的输出,显示频繁的初始标记 (IM)/remark(RM) 周期以及低年轻/终身占用率。您可以看到 Young gen 占用率缓慢增长到 98.30%,之后我们执行预期的
ParNew
(PN) Young GC:
- 实际 GC 日志输出从上述输出中的第一个初始标记 (IM) 开始
14:17:03.057
。与上面类似地被截断,但为了完整性,我确实展示了 ParNew Young GC:
根据 Alexey 的出色观察和建议,我们将尝试在生产中增加 Perm Generation(我会回来报告)。但作为对他猜测的初步验证,我对我们其中一台主机上所有容器 JVM 的 perm gen 使用情况进行了调查,这似乎很合理。在下面的片段中,PID=2979(92% perm gen 容量)是表现出恒定 CMS 收集行为的那个。
java - JMV GC 日志不显示 CMS 事件
这是 GC 活动的捕获:
这是有 Full GC 的时候:
那是世界末日的停顿吗?
我期待看到这个:
但这仅在 JVM 启动后不久发生过一次,以后再也没有发生过。
我在想 JVM 停止使用 CMS GC,所以我检查了:
Concurrent Mark-Sweep GC 似乎运行正常。
在日志中没有 CMS GC 事件的情况下发生 Full GC 是否正常?
如果初始标记和重新标记阶段没有发生,是否意味着没有世界停止暂停?
机器是Windows,24核,JDK 8u101。
以下是使用的标志: