GC正在耗费巨大的时间

时间:2013-11-14 13:33:01

标签: java garbage-collection

我遇到过这样一种情况,即GC需要花费大量时间而不确定是什么原因。这是jstat -gc命令

的输出
S0C     S1C     S0U     S1U EC        EU       OC        OU        PC       PU       YGC  YGCT      FGC FGCT      GCT
77440.0 73088.0 22896.4 0.0 1946624.0 222690.4 4194304.0 3638965.1 262144.0 216641.1 1093 11258.452 3   10031.493 21289.944

Full GC运行3次,完成时间为100031秒,即Avg 55 Min,YGC平均需要15秒。

以下是应用服务器的启动脚本:

-Xms6144m -Xmx6144m -XX:MaxPermSize=256m -Djava.security.policy=/bea/wlserver_10.3/server/lib/weblogic.policy -Dweblogic.ProductionModeEnabled=true -da -Dplatform.home=/bea/wlserver_10.3 -Dwls.home=/bea/wlserver_10.3/server -Dweblogic.home=/bea/wlserver_10.3/server -Dweblogic.management.discover=true -Dwlw.iterativeDev=false -Dwlw.testConsole=false -Dwlw.logErrorsToConsole=false -Dweblogic.ext.dirs=/bea/patch_wls1036/profiles/default/sysext_manifest_classpath -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Duser.timezone=GMT -Dfile.encoding=UTF-8 -Duser.language=en -Duser.country=US -Dweblogic.wsee.wstx.wsat.deployed=false -XX:+DisableExplicitGC

Operating system is Sun OS 5.1
Java version 1.6.0_41

GC算法默认,即Young Gen设置为PS Scavenge,旧GC设置为PS MarkSweep

如此高的数字可能是什么原因,请告诉我。

3 个答案:

答案 0 :(得分:1)

哇,是的,这是一些旧的硬件。原因很简单,6Gb堆是默认串行收集器的一大堆 - 它设计用于不超过几百兆的堆。

我会尝试alternate garbage collectors,直到找到一个给你最低暂停时间。在一个数千兆字节的堆上,如果这么老的机器真的有那么多内存,我会看-XX:+ UseConcMarkSweepGC,如果只有一个CPU核心,那么另外-XX:+ CMSIncrementalMode。

如果你真的有多个CPU,我会看-XX:+ UseParallelGC和-XX:+ UseParallelOldGC。作为最后的手段,您可以查看在Java 6中实验的G1 collector,-XX:+ UseG1GC。

更新:您可以使用jstat -XX:+UseConcMarkSweepGC -XX:+UseParNewGC重新运行-XX:-UseAdaptiveSizePolicy吗?

答案 1 :(得分:0)

运行VMStat 5小时给出了以下结果,我提供了一部分输出:
 交换免费重新发布消息

40336468 4025208 383 5473 465 59
40336132 4025732 383 5477 465 59
40336020 4025732 383 5478 465 59
40335940 4025752 383 5479 465 59
40335860 4025776 383 5479 465 59
40335776 4025796 383 5480 465 59
40335696 4025816 383 5481 465 59
40335584 4025816 383 5482 464 59
40335504 4025836 383 5483 464 59
40335420 4025856 383 5484 464 59

答案 2 :(得分:0)

看看你原来的jstat,这些是我注意到的......

您在老一代中获得了完整的GC,因为它被高度利用(可用于4G的3.5G)。

默认情况下,VM在Young(Eden + Survivor)和Old Generation之间将堆大约分成45/55,但也应用了一些启发式算法。

Eden容量为1.9G,但利用率仅为217M(~12%)。生存空间各约75M,利用率约22M。老一代是4G,利用率高达3.5G。

这对我来说是一个从年轻人到老年人的过度积极推广,混合了不合适的年轻人和老年人的需求。年轻人似乎有点超大,满足您的需求。但是,修复过度激进的促销确实需要Young的空间。

首先,调整年轻人:

-XX:NewRatio=5

这会将Young(Eden + Survivor)设置为总堆的1/6(​​是,1/6不是1/5 )。在你的情况下,~980M而不是1.9G。这会将另一个1G推送到老一代堆。

其次,让我们试着让中等生命的物体不要太快升级。尝试:

-XX:InitialTenuringThreshold=16 -XX:MaxTenuringThreshold=32

但是为了在幸存之前让幸存者保持更长时间,我们需要增加幸存者空间(从伊甸园中划出一点点):

-XX:SurvivorRatio=6

将此与我的第一个答案中的选项以及您的选项相结合,总得出:

-Xms6144m -Xmx6144m -XX:MaxPermSize=256m
-XX:NewRatio=5
-XX:SurvivorRatio=6 -XX:InitialTenuringThreshold=16 -XX:MaxTenuringThreshold=32
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:-UseAdaptiveSizePolicy

您可能想要添加:

-XX:+PrintTenuringDistribution

在调查这些选项时。