Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 偶尔会经历长时间的垃圾收集延迟,为什么?_Java_Garbage Collection - Fatal编程技术网

Java 偶尔会经历长时间的垃圾收集延迟,为什么?

Java 偶尔会经历长时间的垃圾收集延迟,为什么?,java,garbage-collection,Java,Garbage Collection,我很难处理Java垃圾收集问题,也很难解释日志 我的应用程序要求GC所需时间不超过2秒,理想情况下不超过100毫秒 根据前面的一些建议,我正在尝试以下命令行选项: java -XX:MaxGCPauseMillis=100 -XX:NewRatio=9 -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -server -Xmx9g -Xms9g 应用程序有大

我很难处理Java垃圾收集问题,也很难解释日志

我的应用程序要求GC所需时间不超过2秒,理想情况下不超过100毫秒

根据前面的一些建议,我正在尝试以下命令行选项:

 java -XX:MaxGCPauseMillis=100 -XX:NewRatio=9 -XX:+UseConcMarkSweepGC  -XX:+CMSIncrementalMode -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -server -Xmx9g -Xms9g 
应用程序有大量长期存储的对象,这些对象保存在ConcurrentLinkedHashMap中。我偶尔会看到长时间的暂停,最糟糕的情况是长达10秒(这是下面GC日志的倒数第二次了)

以下是我得到的一些输出:

16938.968: [GC 16938.968: [ParNew: 153343K->17022K(153344K), 7.8608580 secs] 6184328K->6122510K(9420160K) icms_dc=7 , 7.8614100 secs] [Times: user=0.63 sys=0.01, real=7.86 secs] 
16947.087: [GC 16947.087: [ParNew: 153342K->17022K(153344K), 7.2604030 secs] 6258830K->6198642K(9420160K) icms_dc=7 , 7.2609780 secs] [Times: user=0.44 sys=0.00, real=7.27 secs] 
16954.614: [GC 16954.614: [ParNew: 153342K->17024K(153344K), 8.4307620 secs] 6334962K->6274625K(9420160K) icms_dc=7 , 8.4313150 secs] [Times: user=0.62 sys=0.01, real=8.43 secs] 
16963.310: [GC 16963.310: [ParNew: 153344K->17023K(153344K), 6.2588760 secs] 6410945K->6350748K(9420160K) icms_dc=7 , 6.2594290 secs] [Times: user=0.48 sys=0.01, real=6.25 secs] 
16969.834: [GC 16969.834: [ParNew: 153343K->17022K(153344K), 6.0274280 secs] 6487068K->6425868K(9420160K) icms_dc=7 , 6.0279830 secs] [Times: user=0.50 sys=0.01, real=6.03 secs] 
16976.122: [GC 16976.123: [ParNew: 153342K->17022K(153344K), 11.7774620 secs] 6562188K->6503030K(9420160K) icms_dc=7 , 11.7780180 secs] [Times: user=0.43 sys=0.04, real=11.78 secs] 
16988.164: [GC 16988.164: [ParNew: 153342K->17024K(153344K), 10.9477920 secs] 6639350K->6579928K(9420160K) icms_dc=7 , 10.9483440 secs] [Times: user=0.37 sys=0.02, real=10.95 secs] 
16999.371: [GC 16999.372: [ParNew: 153344K->17023K(153344K), 9.8828360 secs] 6716248K->6655886K(9420160K) icms_dc=7 , 9.8833940 secs] [Times: user=0.42 sys=0.01, real=9.88 secs] 
17009.509: [GC 17009.509: [ParNew: 153343K->17023K(153344K), 5.0699960 secs] 6792206K->6727987K(9420160K) icms_dc=7 , 5.0705660 secs] [Times: user=0.55 sys=0.01, real=5.07 secs] 
17014.838: [GC 17014.838: [ParNew: 153343K->17023K(153344K), 6.6411750 secs] 6864307K->6790974K(9420160K) icms_dc=7 , 6.6417400 secs] [Times: user=0.37 sys=0.01, real=6.63 secs] 
17021.735: [GC 17021.735: [ParNew: 153343K->17024K(153344K), 8.0545970 secs] 6927294K->6856409K(9420160K) icms_dc=7 , 8.0551790 secs] [Times: user=0.34 sys=0.03, real=8.05 secs] 
17030.052: [GC 17030.053: [ParNew: 153344K->17023K(153344K), 7.9756730 secs] 6992729K->6922569K(9420160K) icms_dc=7 , 7.9762530 secs] [Times: user=0.34 sys=0.01, real=7.98 secs] 
17038.398: [GC 17038.398: [ParNew: 153343K->17022K(153344K), 12.9613300 secs] 7058889K->6990725K(9420160K) icms_dc=7 , 12.9618850 secs] [Times: user=0.39 sys=0.01, real=12.96 secs] 
17051.630: [GC 17051.630: [ParNew: 153342K->17022K(153344K), 6.8942910 secs] 7127045K->7059607K(9420160K) icms_dc=7 , 6.8948380 secs] [Times: user=0.56 sys=0.02, real=6.89 secs] 
17058.798: [GC 17058.798: [ParNew: 153342K->17024K(153344K), 10.0262190 secs] 7195927K->7126351K(9420160K) icms_dc=7 , 10.0267860 secs] [Times: user=0.37 sys=0.01, real=10.02 secs] 
17069.096: [GC 17069.096: [ParNew: 153344K->17023K(153344K), 10.0419500 secs] 7262671K->7195002K(9420160K) icms_dc=7 , 10.0425020 secs] [Times: user=0.40 sys=0.02, real=10.04 secs] 
17079.410: [GC 17079.410: [ParNew: 153343K->17022K(153344K), 13.5389040 secs] 7331322K->7264275K(9420160K) icms_dc=7 , 13.5394610 secs] [Times: user=0.30 sys=0.01, real=13.54 secs] 
17093.223: [GC 17093.224: [ParNew: 153342K->17023K(153344K), 10.5909450 secs] 7400595K->7330446K(9420160K) icms_dc=7 , 10.5915060 secs] [Times: user=0.33 sys=0.00, real=10.58 secs] 
17104.083: [GC 17104.084: [ParNew: 153343K->17024K(153344K), 5.8420210 secs] 7466766K->7392173K(9420160K) icms_dc=7 , 5.8425920 secs] [Times: user=0.57 sys=0.00, real=5.84 secs] 
我花了好几个小时浏览了各种描述JavaGC调优的网页,但没有一个真正让我能够解释上面的日志并提出一个行动方案。任何基于我提供的日志的具体建议都将不胜感激

更新:根据以下问题:

机器有16G RAM,下面是顶部的信息: 内存:总计15483904k,使用15280084k,空闲203820k,缓冲区155684k 交换:总计2031608k,使用1347240k,免费684368k,缓存330044K

这是一个不同的运行,但以下是流程的当前最大输出:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  1016 sanity   17   0 10.2g 6.5g 9464 S    1 44.2  10:24.32 java                      
更新2:一些更详细的日志记录,这似乎导致了400毫秒的延迟:

{Heap before GC invocations=1331 (full 1):
 par new generation   total 153344K, used 153343K [0x00002aaaae200000, 0x00002aaab8860000, 0x00002aaab8860000)
  eden space 136320K, 100% used [0x00002aaaae200000, 0x00002aaab6720000, 0x00002aaab6720000)
  from space 17024K,  99% used [0x00002aaab77c0000, 0x00002aaab885fff0, 0x00002aaab8860000)
  to   space 17024K,   0% used [0x00002aaab6720000, 0x00002aaab6720000, 0x00002aaab77c0000)
 concurrent mark-sweep generation total 7169664K, used 4258496K [0x00002aaab8860000, 0x00002aac6e200000, 0x00002aac6e200000)
 concurrent-mark-sweep perm gen total 21248K, used 13269K [0x00002aac6e200000, 0x00002aac6f6c0000, 0x00002aac73600000)
484.738: [GC 484.738: [ParNew: 153343K->17022K(153344K), 0.3950480 secs] 4411840K->4341689K(7323008K), 0.3954820 secs] [Times: user=0.49 sys=0.07, real=0.40 secs] 
Heap after GC invocations=1332 (full 1):
 par new generation   total 153344K, used 17022K [0x00002aaaae200000, 0x00002aaab8860000, 0x00002aaab8860000)
  eden space 136320K,   0% used [0x00002aaaae200000, 0x00002aaaae200000, 0x00002aaab6720000)
  from space 17024K,  99% used [0x00002aaab6720000, 0x00002aaab77bfb68, 0x00002aaab77c0000)
  to   space 17024K,   0% used [0x00002aaab77c0000, 0x00002aaab77c0000, 0x00002aaab8860000)
 concurrent mark-sweep generation total 7169664K, used 4324666K [0x00002aaab8860000, 0x00002aac6e200000, 0x00002aac6e200000)
 concurrent-mark-sweep perm gen total 21248K, used 13269K [0x00002aac6e200000, 0x00002aac6f6c0000, 0x00002aac73600000)
}

也许200ms的性能限制太严格了,您需要自己管理垃圾收集? 您是否尝试过使用更大的限制?

您看到了吗

还有,看看


一般来说,当您需要如此大的堆时,很难正确地进行GC调优

也就是说,大多数GC挂起时间是由跨年轻垃圾收集的对象的内存复制引起的


ConcurrentLinkedHashMap是否同时使用所有内存持久对象初始化?还是随着应用程序的持续运行,它会慢慢变大?如果是后者,可能很难缩短GC挂起时间,因为有些对象总是存在。如果是前者,您将需要根据持久对象的大小+20%左右调整您的终身生成的大小,并确保您的年轻一代足够大,能够跟上在应用程序过程中创建的临时对象。

从时间上看,GC似乎并不总是运行(请参阅用户时间),因此大部分时间,它都在等待

只是一个猜测:它不是交换吗?机器有多少内存?java进程有多少内存(常驻集大小)

编辑:为什么等待:

看看这个(从你的成绩单上)


这意味着(我猜从GC的开始到结束),12(几乎13)秒过去了。在这13秒中,.39是在用户模式下运行的,.01是在内核模式下运行的。如果时间收集方法不是完全有缺陷的(即,数字确实代表GC进程/线程的运行时间),这意味着至少要等待12秒。

如果您有严格的计时要求,也许您应该查看

RTSJ/Java RTS提供:

API集、语义Java VM增强和JVM到OS层的修改,使Java开发人员能够正确地推理和控制Java应用程序的时态行为


你有没有通过档案器运行你的应用程序,看看你认为memeory正在发生的事情就是实际发生的事情

当我研究这个问题时,我会做的一件事是使用Netbeans探查器(尽管任何探查器都应该向您提供这一点),就是查看活动字节(内存分配),看看那些具有大量已分配字节和已分配objectd的字节是否是我所期望的,是否来自我所期望的地方


您也可以使用探查器查看您的调优效果,在不使用任何tuing参数的情况下运行应用程序,然后添加调优参数并再次运行,然后查看内存中发生了什么。

如果不实际查看,甚至在某些情况下分析代码,可能很难判断

您是否为您的任何对象实现了finalize()?这将导致巨大的GC损失。
同样有趣的是,如果测试运行的堆容量可能为6 Gig,那么如果性能得到了不成比例的提高,这将表明GC正在大量消耗内存。

我认为您的注意力可能有点误导

花一点时间在探查器中查找最大的分配热点。如果代码中只有少数地方发生了大部分分配,请尝试使用对象池,而不是总是构造新对象

集合类和stringbuilder是池的最佳候选对象。当您将它们返回到池中时,请调用Collection.clear()或stringbuilder.setLength(0)方法,以便在下一个调用方希望从池中检索它们时可以使用它们

优化GC的最佳方法是创建更少的对象。有很多消除分配的策略,而池只是其中之一(尽管是我最喜欢的策略之一)


更新:我写这个答案已经五年了,我对池的看法基本上改变了。回到2009年我写这个答案时,我可以经常使用对象池(即使是像StringBuilder这样的简单对象)通过大量的分配来加速紧密的内部循环。现在,很难找到池不会使情况变得更糟的情况。除了线程或连接之外,我几乎从不使用池。尽管如此,它还是一个很好的工具,可以供您使用,即使您不经常使用。

您能发布/链接到C的代码吗oncurrentLinkedHashMap实现?如果这是我发布的实现,请在项目页面上打开一个票证,以便我们可以一起调试。如果不是,请了解您实现的详细信息
[Times: user=0.39 sys=0.01, real=12.96 secs]