为什么有Full GC?

时间:2013-07-09 10:24:01

标签: java garbage-collection jvm

我开始了一个java程序:

java -cp -Xms6072m -Xmx6072m -Xmn2048m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:-DisableExplicitGC 

但Full GC太多了?

2013-07-09T18:16:42.215+0800: [Full GC [PSYoungGen: 11987K->0K(1972032K)] [PSOldGen: 333076K->150949K(408768K)] 345063K->150949K(2380800K) [PSPermGen: 44430K->44430K(262144K)], 0.4696770 secs] [Times: user=0.47 sys=0.00, real=0.47 secs]

2013-07-09T18:16:58.696+0800: [Full GC [PSYoungGen: 12357K->0K(2029568K)] [PSOldGen: 386748K->118215K(383232K)] 399105K->118215K(2412800K) [PSPermGen: 44430K->44430K(262144K)], 0.5117670 secs] [Times: user=0.51 sys=0.00, real=0.51 secs]

我不知道为什么!有人可以帮帮我吗?

3 个答案:

答案 0 :(得分:1)

根据您选择的垃圾收集器,垃圾收集不仅在内存已满时发生。它们可以由各种事件/状态触发。不知怎的,Garbace Collector认为这是开始运行垃圾收集的合适时机。

尝试找出您正在使用的垃圾收集器的特征。防止垃圾收集可能非常棘手,如果没有任何进一步的信息,很难提供任何建议。垃圾收集很少是导致任何问题的真正原因。通常垃圾收集在实时应用程序中至关重要。它最后输出的半秒时间很可能是整个垃圾收集所花费的时间。通常只有一小部分是应用程序暂停的时间。

答案 1 :(得分:1)

我不知道“太多”是什么意思,但我相信这个意图:

-XX:-DisableExplicitGC

是禁用对显式垃圾收集的调用,即System.gc()或Runtime.getRuntime()。gc()。如果这是意图,减去是错误的,它应该是:

-XX:+ DisableExplicitGC

答案 2 :(得分:1)

根据您的命令行,您的堆几何:

  • 旧空间:4 GiB
  • 年轻空间:2 GiB(幸存者为1.5 GiB eden + 0.5 GiB,如果适用默认比例)

根据您的GC日志,首次发生完整GC时

  • 旧空间有3.3 GiB(从4 GiB)
  • 年轻空间1.1 GiB(来自2 GiB)

当JVM启动年轻GC时,必须确保它具有足够的可用空间以容纳促销对象。

不幸的是,你还没有包含次要GC记录,所以我必须进一步推测。

JVM在年轻空间中看到1.1 GiB的数据,在旧空间中只看到大约0.7 GiB的可用空间,因此它可能没有足够的可用空间来容纳提升的对象。这可能是启动完整GC的原因。

但是,如果伊甸园有足够的自由空间,为什么年轻的GC被触发呢?
以下是几个可能的原因:

  • 自适应大小调整政策可能已推翻伊甸园(从1.5 GiB到〜1GiB)
  • 大数组的分配可能会触发年轻的GC(变成完整的GC)

另请注意,-XX:-DisableExplicitGC标志没有效果(减去而不是加号),因此所有这些奇怪的行为可能都是由System.gc()

引起的