5

我正在研究一个完全用 Java 编写的内存数据库。我们有一个向系统提供数据的输入源,这是提取/加载阶段。运行此程序时,我注意到 JVM 挂起,根本原因是触发了 Full GC。然后应用程序被冻结,随后出现 OutOfMemory 错误(超出 GC 开销限制)

检查 GC 日志发现有很多新旧垃圾收集。令人惊讶的一件事是期望幸存者的大小是负数。我试图理解为什么会这样?有没有人遇到过这个?

环境:

  • Windows7 专业服务包1
  • 戴尔 Precision T7500,24 核
  • 64 位操作系统 192 GB 内存

Sun JDK 版本: 1.7.0_13-b20(64 位)

JVM设置:

  • -Xmx100g
  • -Xms100g
  • -详细:gc
  • -Xloggc:C:/temp/logs/gc.log
  • -XX:+PrintGCTimeStamps
  • -XX:+PrintGC详情
  • -XX:+PrintTenuringDistribution
  • -XX:MaxPermSize=256m
  • -XX:+UseParallelOldGC

GC 日志摘录(这不是完整的日志):

0.666: [GC Desiredsurvivor size 178913280 bytes, new threshold 7 (max 15) [PSYoungGen: 524289K->4431K(30583488K)] 524289K->4503K(100488576K), 0.0052536 secs] [Times: user=0.03 sys=00. =0.01 秒]

0.671:[完整 GC(系统)[PSYoungGen:4431K->0K(30583488K)][ParOldGen:72K->4096K(69905088K)]4503K->4096K(100488576K)[PSPermGen:8852K->8847K(21248K7)],0835K7)。 secs] [Times: user=0.08 sys=0.00, real=0.09 secs]

12.306:[GC 所需的幸存者大小 178913280 字节,新阈值 7(最大 15)[PSYoungGen:26214464K->389676K(30583488K)] 26218560K->393868K(100488576K),0.1907519 6 秒] [Times.69,真实用户 = 0.0 =0.19 秒]

19.845:[GC 期望的幸存者大小 178913280 字节,新阈值 7(最大 15)[PSYoungGen:26604140K->4369012K(30583488K)] 26608334K->4539738K(100488576K),2.0671426 秒] [时间:1671426 秒] [时间:用户。6 =2.07 秒]

31.930:[GC 期望的幸存者大小 178913280 字节,新阈值 7(最大 15)[PSYoungGen:30583476K->4368998K(30583488K)] 30764447K->5793376K(100488576K),2.4316614 秒] [时间:12.0 秒,用户 = 4.2 秒=2.43 秒]

43.950:[GC 期望的幸存者大小 178913280 字节,新阈值 7(最大 15)[PSYoungGen:30583462K->4369018K(30583488K)] 32008283K->10474103K(100488576K),3.086846,3176 秒] [时间。 =3.09 秒]

57.851:[GC 所需的幸存者大小 -954466304 字节,新阈值 6(最大 15)[PSYoungGen:30583482K->4369011K(16019904K)] 36688571K->19053916K(85924992K),5.0616910 秒] [时间:21 用户,558 秒真实=5.06 秒]

67.849:[GC 所需的幸存者大小 -954466304 字节,新阈值 5(最大 15)[PSYoungGen:16019891K->7854065K(23301696K)] 30706222K->22540396K(93206784K),1.9574226 秒= sys=0.0真实=1.96 秒]

74.940:[GC 所需的幸存者大小 -954466304 字节,新阈值 4(最大 15)[PSYoungGen:19504945K->11650800K(23301696K)]34191281K->27450594K(93206784K),3.2006784K),3.2006784K),3.208939 秒] [时间=1,55.41 秒] [时间。真实=3.21 秒]

83.683:[GC 期望的幸存者大小 -954466304 字节,新阈值 3(最大 15)[PSYoungGen:23301680K->11650785K(23301696K)] 39101518K->32434323K(93206784K),4.8106784K),4.8105989 秒] [系统用户 3,689 秒] [时间=10.2.2。真实=4.81 秒]

93.647:[GC 期望的幸存者大小 -954466304 字节,新阈值 2(最大 15)[PSYoungGen:23301665K->10083445K(23301696K)] 44085203K->35191108K(93206784K),3.9406784K),3.9481522 秒] [时间=8.0.0.7.77真实=3.95 秒]

102.406:[GC 期望的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:21734325K->10417779K(23301696K)] 46841988K->39667600K(93206784K),4.7030362 秒 9 = sys.92 用户:5,62 秒。真实=4.70 秒]

112.109:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:22068659K->5501380K(23301696K)] 51318480K->45289996K(93206784K),5.6499475 秒] [时间=2.3真实=5.65 秒]

122.858:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:17152260K->5829244K(23301696K)] 56941300K->51036174K(93206784K),3.9348524 秒] [时间。真实=3.93 秒]

132.599:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:17480124K->4411050K(23301696K)] 62703442K->55124929K(93206784K),3.2682313 秒] [Times.0.0.0.0.0。真实=3.27 秒]

141.869:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:16061930K->5983419K(23301696K)]66775809K->61080627K(93206784K),3.1606784K),3.1606784K),3.1606784K),3.1660854 秒] [时间=9.4 用户,383 秒] [时间:9.4 秒。真实=3.17 秒]

149.996:[GC 期望的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:17634299K->5335607K(23301696K)] 72731507K->65656597K(93206784K),4.4767380 秒] [时间=12。真实=4.48 秒]

154.473:[Full GC [Psyounggen:5335607K-> 0K(23301696K)]时间:user=518.19 sys=3.43, real=55.61 secs]

210.083:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:1942K->96K(23301696K)] 29189919K->29188073K(93206784K),0.0512343 秒] [时间:用户 = 0.50 sys=真实=0.05 秒]

210.134:[Full GC [Psyounggen:96K-> 0K(23301696K)]时间:用户=236.31 系统=0.19,真实=15.51 秒]

239.525:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:11650880K->4622965K(23301696K)]40838696K->33810782K(93206784K),1.2739696 秒] [时间=0.0.0.0.01 秒]真实=1.27 秒]

248.572:[GC 期望的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:16273845K->4009690K(23301696K)] 45461663K->37894227K(93206784K),2.3307284K),2.3307284 秒] [时间=0.4.4.4真实=2.33 秒]

256.854:[GC 期望的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:15660570K->5707092K(23301696K)] 49545113K->43643553K(93206784K),2.5595566 秒] [时间=00000566 秒]真实=2.56 秒]

265.471:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:17357972K->4996932K(23301696K)] 55294440K->48690372K(93206784K),2.8941178 秒] [Times.真实=2.89 秒]

275.795:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:16647812K->3781542K(23301696K)] 60342280K->52491436K(93206784K),2.6206784K,2.62406784K),2.6206784K)[时间=0.00,471 秒] [时间=0.00 用户=471 秒真实=2.63 秒]

284.083:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:15432422K->5815192K(23301696K)] 64142316K->58360954K(93206784K),2.3724770 秒] [时间=0.00 秒:4.8 秒]真实=2.37 秒]

291.659:[GC 所需的幸存者大小 -954466304 字节,新阈值 1(最大 15)[PSYoungGen:17466072K->5357588K(23301696K)] 70011840K->63780322K(93206784K),3.0063028 秒] [时间=0063028 秒]真实=3.01 秒]

299.322:[GC 期望的幸存者大小 -1228210176 字节,新阈值 2(最大 15)[PSYoungGen:17008468K->6341939K(23301696K)] 75431206K->70078817K(93206784K),4.19939305 秒 5 秒] [时间。真实=4.20 秒]

303.523:[Full GC [Psyounggen:6341939K-> 0K(23301696K)]

正如您在上面的日志中看到的 57.851 秒,我们有一个负的期望幸存者大小,我不知道为什么会这样?

这看起来像内存泄漏吗?

任何帮助将不胜感激。我还附上了堆的visualvm快照 可视 VM 堆快照

4

1 回答 1

4

是的,你的问题似乎是你有太多的活动对象。“GC Overhead Limit Exceeded”意味着 GC 运行,花费了很长时间并且释放的很少。您可以调整一些旋钮来控制控制它的阈值,但这些不会帮助您提高性能。

在创建内存密集型模拟(也是 100 - 120GB 最大堆)时,我遇到了完全相同的问题。我的解决方案是远离对象来存储数据,并将所有内容保存在原始 int[] 中。这个工作最终变成了一个名为Banana的新开源项目,它支持一些原始数据结构。Banana 实际上是基于它自己的内存管理的数据结构,您可以获得完全动态的数据结构,而无需对象的开销。继续阅读项目 wiki,它记录了事情是如何工作的,并获得了示例代码和基准。

于 2013-08-01T09:35:51.887 回答