我在执行JUnit测试时收到此错误消息:
java.lang.OutOfMemoryError: GC overhead limit exceeded
Run Code Online (Sandbox Code Playgroud)
我知道它OutOfMemoryError是什么,但GC开销限制意味着什么?我怎么解决这个问题?
我在一个程序中得到这个错误,该程序创建了几个(几十万个)HashMap对象,每个对象有几个(15-20)个文本条目.在提交到数据库之前,必须收集这些字符串(不会分解成较小的数量).
根据Sun的说法,如果在垃圾收集中花费了太多时间,则会发生错误:如果超过98%的总时间花在垃圾收集上,并且不到2%的堆被恢复,则会抛出OutOfMemoryError. ".
显然,可以使用命令行将参数传递给JVM
第一种方法工作正常,第二种方法在另一个java.lang.OutOfMemoryError中结束,这次是关于堆的.
所以,问题:对于特定的用例(即几个小的HashMap对象),是否有任何编程替代方案?例如,如果我使用HashMap clear()方法,问题就会消失,但HashMap中存储的数据也会消失!:-)
StackOverflow中的相关主题也讨论了该问题.
Java 7已经出现了一段时间了,但我找不到任何关于垃圾收集器配置的好资源,特别是新的G1收集器.
我的问题:
任何人都可以解释增加maxpermsize和max heap size的副作用吗?
我知道有时候,当我们遇到outofmemory问题时,我们会增加-Xmx.但我只是想知道当我们增加-Xmx时是否需要记住任何副作用.增加maxpermsize如何影响运行时?
谢谢.
我在用
java version "1.7.0_09"
Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode)
Run Code Online (Sandbox Code Playgroud)
与G1垃圾收集器.JVM的论点是
-server -Xss4096k -XX:MaxPermSize=512m -XX:PermSize=512m -Xms30G
-Xmx30G -Xnoclassgc -XX:+UseNUMA -XX:+UseFastAccessorMethods
-XX:ReservedCodeCacheSize=48m -XX:+UseStringCache
-XX:+UseGCOverheadLimit -Duser.timezone=EET
-Xmaxf1 -XX:+UseCompressedOops -XX:+DisableExplicitGC
-XX:+AggressiveOpts -XX:CMSInitiatingOccupancyFraction=70
-XX:+ParallelRefProcEnabled -XX:+UseAdaptiveSizePolicy
-XX:MaxGCPauseMillis=500 -XX:+UseG1GC
-XX:InitiatingHeapOccupancyPercent=0
-XX:GCPauseIntervalMillis=10000 -XX:+PrintGCDetails
-XX:+PrintHeapAtGC -XX:+PrintGCDateStamps -Xloggc:gc.log
Run Code Online (Sandbox Code Playgroud)
但是,我正在经历完全GC扫描,没有任何明显的原因,如何摆脱它们?
GC日志与之前事件的尾部:
{Heap before GC invocations=206 (full 8):
garbage-first heap total 31457280K, used 18323299K [0x00007fc6eb800000, 0x00007fce6b800000, 0x00007fce6b800000)
region size 8192K, 768 young (6291456K), 31 survivors (253952K)
compacting perm gen total 524288K, used …Run Code Online (Sandbox Code Playgroud) 有时,在测试机器(Windows)上,Java full GC需要20秒以上.GC日志显示real时间非常高,user也很高,但不是很高(大约3秒).在一个案例中,它是:
21.2209796 secs [Times: user=3.76 sys=0.45, real=21.22 secs]
Run Code Online (Sandbox Code Playgroud)
可能是什么原因?我怀疑但现在不想说.
找出根本原因的最简单方法是什么?如果您不了解Windows但知道Linux,那也是一个选项:测试可以在Linux上重新运行.
该过程开始如下:
"%JAVA_HOME%\bin\java.exe" -verbose:gc -XX:+PrintGCDetails
-XX:+PrintGCDateStamps -Xloggc:publish.gc.log
-XX:PermSize=256m -XX:MaxPermSize=1024m -Xms1024m
-Xmx3072m -XX:NewSize=352m -XX:MaxNewSize=352m
-XX:SurvivorRatio=6
Run Code Online (Sandbox Code Playgroud)
我不知道为什么NewSize,XX:MaxNewSize并且SurvivorRatio被使用.MaxPermSize是必需的,因为它是一个OSGi环境.完整的线程转储不会显示任何特殊内容.
完整的GC的完整日志是(抱歉,长):
2014-05-06T21:38:18.735-0700: 150.261: [Full GC [PSYoungGen: 23614K->0K(309952K)] [PSOldGen: 693188K->311405K(688128K)] 716802K->311405K(998080K) [PSPermGen: 45120K->45120K(262144K)], 1.4533481 secs] [Times: user=1.45 sys=0.01, real=1.45 secs]
2014-05-06T21:38:58.379-0700: 189.907: [Full GC [PSYoungGen: 1664K->0K(335488K)] [PSOldGen: 668139K->283959K(688128K)] 669803K->283959K(1023616K) [PSPermGen: 46688K->46688K(262144K)], 1.3466773 secs] [Times: user=1.34 sys=0.00, real=1.35 secs]
2014-05-06T21:39:44.082-0700: 235.613: [Full GC [PSYoungGen: …Run Code Online (Sandbox Code Playgroud) G1垃圾收集器在Java(6)的最新版本中是否仍被认为是实验性的?它是安全的并且可以用于生产吗?
编辑:我指的是Oracle JVM.