0

我启动了一个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]

我不知道为什么!任何人都可以帮助我吗?

4

3 回答 3

1

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

-XX:-DisableExplicitGC

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

-XX:+DisableExplicitGC

于 2013-07-09T11:10:44.683 回答
1

根据您选择的垃圾收集器之一,垃圾收集不仅会在内存已满时发生。它们可以由各种事件/状态触发。不知何故,垃圾收集器认为现在是开始运行垃圾收集的正确时机。

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

于 2013-07-09T10:50:31.477 回答
1

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

  • 旧空间:4 GiB
  • 年轻空间:2 GiB(1.5 GiB eden + 0.5 GiB insurvivor,如果适用默认比率)

根据您的 GC 日志,当第一次 Full GC 发生时

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

当JVM启动young GC时,它必须确保old中有足够的空闲空间来容纳promote object。

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

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

但是,如果伊甸园中有足够的空闲空间,为什么此时会触发年轻 GC?
以下是几个可能的原因:

  • 自适应大小调整策略可能已经规避了伊甸园(从 1.5 GiB 到 ~ 1GiB)
  • 分配大数组可能会触发young GC(变成full GC)

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

于 2013-07-10T20:55:18.407 回答