JavaG1GC处理引用对象的速度很慢

JavaG1GC处理引用对象的速度很慢,java,garbage-collection,g1gc,Java,Garbage Collection,G1gc,我已经在Java上运行了计数器。它工作24小时,每秒点击100次。 在白天,GC处理时间从20-60 ms缓慢上升到10000-60000 ms,然后下降到20-60 ms。这种模式不时重复。从GC日志中,我发现GC在处理引用对象(refproc)上花费的时间最多。那么GC时间这么长的原因是什么呢 Server: Amazon EC2 m1.small OS: Ubuntu 10.04.3 LTS Java: Oracle 1.7.0_07 GC日志示例: 2012-09-13T16:51:2

我已经在Java上运行了计数器。它工作24小时,每秒点击100次。 在白天,GC处理时间从20-60 ms缓慢上升到10000-60000 ms,然后下降到20-60 ms。这种模式不时重复。从GC日志中,我发现GC在处理引用对象(refproc)上花费的时间最多。那么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)]
时间-“参考过程”图:

我在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弱引用的一些问题。

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

如果这是不可能的,您必须找到适合您的应用程序行为的最佳堆大小和GC算法。这将是一种反复试验的方法。你肯定得通过考试。当您的应用程序行为改变或负载模式改变时,您现在进行的调优可能会再次变得低效

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

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

通过反复试验。

重要的是,我所有的跑步都要使用Yourkit profiler。我安装了OpenJDK7的fastdebug版本。在这个版本中有一个参数-XX:+TraceReferenceGC。使用此参数运行后,gc日志显示了大约5000个终结器。通过关闭套件的插座探针解决了此问题。

您是否看到其他采集器存在相同的行为?(以确定您的程序是否正在执行某些操作或G1中的某些异常操作)与默认收集器的行为相同。您是否知道您有多少个引用对象,例如
jmap-histo{pid}
您是否可以按照您给出的方式发布更多的GC日志;添加Ref Proc时间为505005000的情况Ref Proc时间为505005000的情况:您还可以使用
-Xnoclassgc
禁用引用检查。
    -XX:+UseConcMarkSweepGC        
    -XX:SurvivorRatio=10 
    -XX:TargetSurvivorRatio=90 
    -XX:MaxTenuringThreshold=30