【问题标题】:Java G1 GC Processing Reference objects works slowJava G1 GC 处理参考对象工作缓慢
【发布时间】:2012-09-14 17:18:54
【问题描述】:

我已经在 J​​ava 上运行了计数器。它可以 24 小时工作,并且点击率大约每秒 100 次。 白天 GC 处理时间从 20-60 毫秒缓慢上升到 10000-60000 毫秒,然后下降到 20-60 毫秒。这种模式不时重复。从 GC 日志中,我发现大部分时间 GC 都花在处理引用对象(Ref Proc)上。那么GC时间这么长的原因可能是什么呢?

Server: Amazon EC2 m1.small
OS: Ubuntu 10.04.3 LTS
Java: Oracle 1.7.0_07

GC 日志示例:

2012-09-13T16:51:20.091+0400: 167239.936: [GC pause (young), 62.58395400 secs]
...
[Other: 62489.7 ms]
    [Choose CSet:   0.0 ms]
    [Ref Proc: 62433.9 ms]
    [Ref Enq:   0.0 ms]
    [Free CSet:   0.7 ms]
[Eden: 200M(200M)->0B(199M) Survivors: 4096K->5120K Heap: 578M(1024M)->380M(1024M)]

时间 - “Ref Proc”图表:

09:37:59 - 242.4 ms
09:38:50 - 226.0 ms
09:39:00 - 83.6 ms
...
11:45:22 - 451.8 ms
11:46:04 - 489.3 ms
11:46:46 - 505.6 ms
...
14:05:40 - 1027.3 ms
14:06:01 - 796.6 ms
14:06:35 - 1064.0 ms
...
15:44:32 - 1920.4 ms
15:45:04 - 2116.7 ms
15:45:39 - 2196.8 ms
...
16:19:07 - 3983.3 ms
16:19:43 - 4494.9 ms
16:20:16 - 4065.2 ms
...
16:33:11 - 7690.1 ms
16:33:50 - 8501.4 ms
16:34:28 - 8059.3 ms
...
16:47:14 - 51378.6 ms
16:49:11 - 57529.2 ms
16:51:20 - 62433.9 ms
16:53:00 - 46.1 ms
16:53:30 - 45.5 ms
16:54:03 - 45.0 ms
...
16:54:38 - 57.0 ms
16:55:09 - 20.9 ms
16:55:43 - 21.3 ms
...
16:09:45 - 134.3 ms
16:10:21 - 142.1 ms
16:10:58 - 147.5 ms
...
17:18:51 - 177.3 ms
17:19:27 - 135.8 ms
17:20:03 - 179.6 ms

我在java源参数中找到了PrintReferenceGC。接下来显示 GC 日志

[SoftReference, 0 refs, 0.0000050 secs]
[WeakReference, 6 refs, 0.0000030 secs]
[FinalReference, 113 refs, 0.0011180 secs]
[PhantomReference, 0 refs, 0.0000020 secs]
[JNI Weak Reference, 3.9010450 secs]

这是JNI弱引用的一些问题。

【问题讨论】:

  • 你看到其他收藏家有同样的行为吗? (确定它是你的程序正在做的事情还是 G1 中的一些奇怪的事情)
  • 使用默认收集器是相同的行为。
  • 你知道你有多少参考对象吗? jmap -histo {pid}
  • 你能不能再发几条你给的GC日志;添加 Ref Proc 时间为 50,500,5000 的情况
  • Ref Proc时间为50、500、5000的情况:files.gorbunak.user.dev.topadvert.ru/random/cledv6wz8q.txt

标签: java garbage-collection g1gc


【解决方案1】:

我所有的运行都使用 Yourkit 分析器,这一点很重要。我安装了 OpenJDK7 的 fastdebug 版本。在这个版本有一个参数-XX:+TraceReferenceGC。使用此参数运行后 gc 日志显示大约 5000 一些终结器。此问题已通过关闭 Yourkit 的套接字探针得到解决。

【讨论】:

  • 您也可以使用-Xnoclassgc 禁用参考检查。
【解决方案2】:

作为第一步,您可以使用 VisualVM 或任何工具来分析您的堆使用模式。您可能会通过优化代码、检查对象创建的热点来获得解决方案,这应该是一个永久性的解决方案。

如果这不可能,您必须找到适合您的应用程序行为的最佳堆大小和 GC 算法。这将是一种试错法。你一定要通过tuning doc。当您的应用程序行为发生变化或负载模式发生变化时,您现在所做的调整可能会再次变得低效。

尝试找到适合您的收藏家。您将调整一些参数,例如

    -XX:+UseConcMarkSweepGC        
    -XX:SurvivorRatio=10 
    -XX:TargetSurvivorRatio=90 
    -XX:MaxTenuringThreshold=30

通过反复试验。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 2019-11-12
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多