我正在使用完全用Java编写的内存数据库。我们有一个输入源,它为系统提供数据,这就是提取/加载阶段。在运行时,我注意到JVM正在挂起,其根本原因是Full GC被触发。然后应用程序冻结,然后出现OutOfMemory错误(GC Overhead Limit Exceeded)
检查GC日志显示了很多垃圾收集,包括年轻人和老年人。 令人惊讶的是,Desired Survivor的规模是负面的。我想知道为什么会这样?有没有人遇到过这个?
环境:
Sun JDK版本: 1.7.0_13-b20(64位)
JVM设置:
GC日志摘录(这不是完整日志):
0.666:[GC 期望幸存者大小178913280字节,新阈值7(最多15) [PSYoungGen:524289K-> 4431K(30583488K)] 524289K-> 4503K(100488576K),0.0052536 secs] [次:用户= 0.03 sys = 0.00,real = 0.01 secs]
0.671:[全GC(系统)[PSYoungGen:4431K-> 0K(30583488K)] [ParOldGen:72K-> 4096K(69905088K)] 4503K-> 4096K(100488576K)[PSPermGen:8852K-> 8847K(21248K)],0.0853597秒] [时间:用户= 0.08 sys = 0.00,实际= 0.09秒]
12.306:[GC 期望幸存者大小178913280字节,新阈值7(最多15) [PSYoungGen:26214464K-> 389676K(30583488K)] 26218560K-> 393868K(100488576K),0.1907519 secs] [次:用户= 0.69 sys = 0.69,real = 0.19 secs]
19.845:[GC 期望幸存者大小178913280字节,新阈值7(最多15) [PSYoungGen:26604140K-> 4369012K(30583488K)] 26608334K-> 4539738K(100488576K),2.0671426 secs] [次:用户= 12.67 sys = 10.64,真实= 2.07秒]
31.930:[GC 期望幸存者大小178913280字节,新阈值7(最多15) [PSYoungGen:30583476K-> 4368998K(30583488K)] 30764447K-> 5793376K(100488576K),2.4316614 secs] [次:用户= 14.32 sys = 12.07,实际= 2.43秒]
43.950:[GC 期望幸存者大小178913280字节,新阈值7(最多15) [PSYoungGen:30583462K-> 4369018K(30583488K)] 32008283K-> 10474103K(100488576K),3.0868838 secs] [次:用户= 31.76 sys = 10.64,实际= 3.09秒]
57.851:[GC 期望的幸存者大小-954466304字节,新阈值6(最多15) [PSYoungGen:30583482K-> 4369011K(16019904K)] 36688571K-> 19053916K(85924992K),5.0616910 secs] [次:用户= 45.58 sys = 21.95,真实= 5.06秒]67.849:[GC 期望的幸存者大小-954466304字节,新阈值5(最多15) [PSYoungGen:16019891K-> 7854065K(23301696K)] 30706222K-> 22540396K(93206784K),1.9574226 secs] [次:用户= 35.38 sys = 0.00,real = 1.96 secs]
74.940:[GC 期望的幸存者大小-954466304字节,新阈值4(最多15) [PSYoungGen:19504945K-> 11650800K(23301696K)] 34191281K-> 27450594K(93206784K),3.2089939 secs] [次:用户= 54.41 sys = 1.51,真实= 3.21秒]
83.683:[GC 期望的幸存者大小-954466304字节,新阈值3(最多15) [PSYoungGen:23301680K-> 11650785K(23301696K)] 39101518K-> 32434323K(93206784K),4.8105989 secs] [次:用户= 65.82 sys = 10.30,实际= 4.81秒]
93.647:[GC 期望的幸存者大小-954466304字节,新阈值2(最多15) [PSYoungGen:23301665K-> 10083445K(23301696K)] 44085203K-> 35191108K(93206784K),3.9481522 secs] [次:用户= 54.77 sys = 8.02,真实= 3.95秒]
102.406:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:21734325K-> 10417779K(23301696K)] 46841988K-> 39667600K(93206784K),4.7031362 secs] [次:用户= 63.29 sys = 9.50,实际= 4.70秒]
112.109:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:22068659K-> 5501380K(23301696K)] 51318480K-> 45289996K(93206784K),5.6499475 secs] [次:用户= 51.39 sys = 23.81,real = 5.65 secs]
122.858:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:17152260K-> 5829244K(23301696K)] 56941300K-> 51036174K(93206784K),3.9348524 secs] [次:用户= 47.49 sys = 11.48,真= 3.93秒]
132.599:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:17480124K-> 4411050K(23301696K)] 62703442K-> 55124929K(93206784K),3.2682313 secs] [次:用户= 35.46 sys = 10.86,real = 3.27 secs]
141.869:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:16061930K-> 5983419K(23301696K)] 66775809K-> 61080627K(93206784K),3.1660854 secs] [次:用户= 38.39 sys = 9.45,real = 3.17 secs]
149.996:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:17634299K-> 5335607K(23301696K)] 72731507K-> 65656597K(93206784K),4.4767380 secs] [次:用户= 55.41 sys = 12.67,真实= 4.48秒]154.473:[Full GC [PSYoungGen:5335607K-> 0K(23301696K)] [ParOldGen:60320990K-> 29187977K(69905088K)] 65656597K-> 29187977K(93206784K)[PSPermGen:53148K-> 53088K(106560K) )],55.6080316 secs] [次:用户= 518.19 sys = 3.43,真实= 55.61秒]
210.083:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:1942K-> 96K(23301696K)] 29189919K-> 29188073K(93206784K),0.0512343 secs] [次:用户= 0.50 sys = 0.00,real = 0.05 secs]
210.134:[Full GC [PSYoungGen:96K-> 0K(23301696K)] [ParOldGen:29187977K-> 29187816K(69905088K)] 29188073K-> 29187816K(93206784K)[PSPermGen:53088K-> 53087K(106624K) )],15.5128928秒] [时间:用户= 236.31 sys = 0.19,真实= 15.51秒]
239.525:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:11650880K-> 4622965K(23301696K)] 40838696K-> 33810782K(93206784K),1.2739696 secs] [次:用户= 23.01 sys = 0.00,real = 1.27 secs]
248.572:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:16273845K-> 4009690K(23301696K)] 45461663K-> 37894227K(93206784K),2.3307283 secs] [次:用户= 41.84 sys = 0.00,real = 2.33 secs]
256.854:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:15660570K-> 5707092K(23301696K)] 49545113K-> 43643553K(93206784K),2.5595566 secs] [次:用户= 46.05 sys = 0.00,real = 2.56 secs]
265.471:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:17357972K-> 4996932K(23301696K)] 55294440K-> 48690372K(93206784K),2.8941178 secs] [次:用户= 52.21 sys = 0.00,real = 2.89 secs]
275.795:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:16647812K-> 3781542K(23301696K)] 60342280K-> 52491436K(93206784K),2.6240427 secs] [次:用户= 47.18 sys = 0.00,real = 2.63 secs]
284.083:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:15432422K-> 5815192K(23301696K)] 64142316K-> 58360954K(93206784K),2.3724770 secs] [次:用户= 42.68 sys = 0.00,real = 2.37 secs]
291.659:[GC 期望的幸存者大小-954466304字节,新阈值1(最多15) [PSYoungGen:17466072K-> 5357588K(23301696K)] 70011840K-> 63780322K(93206784K),3.0063028 secs] [次:用户= 54.20 sys = 0.00,real = 3.01 secs]
299.322:[GC 期望的幸存者大小-1228210176字节,新阈值2(最多15) [PSYoungGen:17008468K-> 6341939K(23301696K)] 75431206K-> 70078817K(93206784K),4.1999305 secs] [次:用户= 65.35 sys = 5.13,真实= 4.20秒]
303.523:[Full GC [PSYoungGen:6341939K-> 0K(23301696K)] [ParOldGen:63736877K-> 38098305K(69905088K)] 70078817K-> 38098305K(93206784K)[PSPermGen:53125K-> 53125K(103360K) )],41.2081882秒]
你可以在上面的日志中注意到57.851秒,我们有一个负的期望幸存者大小,我不知道为什么会这样?
这看起来像内存泄漏吗?
非常感谢任何帮助。我还附加了visualvm的快照
答案 0 :(得分:4)
是的,您的问题似乎是您只有太多的实时对象。 “GC Overhead Limit Exceeded”意味着GC运行,花了很长时间并且释放得很少。 你可以调整一些旋钮来控制控制它的阈值,但这些不会帮助你提高性能。
我在创建内存密集型模拟时遇到了完全相同的问题(也是100 - 120GB最大堆)。 我的解决方案是远离Objects来存储数据,并将所有内容保存在原始int []中。 最终变成了一个名为Banana的新开源项目,该项目支持一些原始数据结构。 Banana实际上是基于它自己的内存管理的数据结构,你可以获得完全动态的数据结构而不需要对象的开销。 继续阅读项目维基,它记录了工作原理,并获得了示例代码和基准测试。