java - 几天后 GC 暂停变得很长

标签 java memory-leaks garbage-collection jvm g1gc

我正在运行一个构建系统。我们曾经使用 CMS 收集器,但我们开始在非常长的完整 GC 周期下受苦,吞吐量(不进行 GC 的时间)约为 90%。所以我现在决定切换到 G1,假设即使我有更长的整体 GC 时间,暂停也会更短,从而确保更高的可用性。所以这个想法似乎比我预期的更有效,我几乎 3 天没有看到完整的 GC,吞吐量是 97%,整体 GC 性能更好。 (所有截图和数据均来自GCViewer)

Normal

到现在(第 6 天)。今天系统简直疯了。旧空间的利用率略低于 100%。我看到 Full GC 几乎每 2-3 分钟左右触发一次: Berzerk!

旧空间利用率: Old space

堆大小为 20G(总共 128G Ram)。我目前使用的标志是:

-XX:+UseG1GC
-XX:MaxPermSize=512m
-XX:MaxGCPauseMillis=800
-XX:GCPauseIntervalMillis=8000 
-XX:NewRatio=4
-XX:PermSize=256m
-XX:InitiatingHeapOccupancyPercent=35
-XX:+ParallelRefProcEnabled

加上日志标记。我似乎缺少的是 -XX:+ParallelGCThreads=20 (我有 32 个处理器),默认值应该是 8。我还从 oracle 中了解到,建议使用 - XX:+G1NewSizePercent=4 对于 20G 堆,默认应该是 5。

我正在使用 Oracle Corporation 的 Java HotSpot(TM) 64 位服务器 VM 1.7.0_76

您有什么建议?我有明显的错误吗?改变什么? 我只给Java 20G是不是太贪心了?这里的假设是,给它太多的堆将意味着更长的 GC,因为要清理的东西更多(农民逻辑)。

PS:应用程序不是我的。对我来说,它是一个盒子产品。

最佳答案

What would you suggest? Do I have obvious mistakes? What to change? Am I do greedy by giving Java only 20G? The assumption here is that giving it too much heap would mean longer GC as there is simply more to clean (peasant logic).

如果它触发了完整的 GC 但您的占用率保持在 20GB 附近,那么 GC 可能根本没有足够的喘息空间来满足大量分配的需求或满足其某些目标(吞吐量、暂停时间) ),强制执行完整的 GC 作为后备。

因此您可以尝试增加堆限制或放宽吞吐量目标。

正如我之前在评论中提到的,您还可以尝试升级到 java8 以改进 G1 启发式算法。

有关“berzerk”行为的 GC 日志的进一步建议将很有用。

关于java - 几天后 GC 暂停变得很长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28901443/

相关文章:

c# - 简单的 WPF 示例会导致内存增长失控

.net - 不应该直接调用垃圾收集器的原因

c# - 是否有可能对当前被 `using` block 消耗的引用进行 GC?

java - RotateTransition 当前角度 javafx2

java - 从 BaseAdapter 的 GridView 中检索 ArrayList 值

java - 无法创建媒体播放器

c++ - 在 C++ 中新建/删除奇怪的内存泄漏

memory-leaks - 了解崩溃日志 "this may be a leak"

java - 为高分配率调整 JVM

java - 将类转换为 JSONObject