在哪种情况下,年轻一代的Java垃圾收集持续多久?

时间:2011-11-17 14:25:21

标签: java garbage-collection

昨天我们在一个JBoss应用服务器的服务器日志中输出了以下GC:

51628.286: [GC 51628.288: [ParNew: 1843200K->204800K(1843200K), 21.3196040 secs]
5177730K->3743415K(7987200K), 21.3217870 secs]
[Times: user=1.38 sys=0.33, real=21.32 secs] 

我理解这样的输出:年轻一代的大小为1843200K。前一代的尺寸为1843200K,尺寸在204800K之后。收集持续了21.3秒。

通常我们的年轻一代收藏持续时间<1秒。 yg集合在哪种情况下持续这么久?

我们的JVM参数:

-server 
-verbose:gc
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails 
-XX:NewRatio=3
-XX:+UseConcMarkSweepGC 
-XX:+UseParNewGC 
-XX:+UseCMSCompactAtFullCollection 
-XX:CMSInitiatingOccupancyFraction=60 
-XX:MaxPermSize=256m 
-Xss512k 
-Xms8000m 
-Xmx8000m

java版:

java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)

谢谢, 烫发

4 个答案:

答案 0 :(得分:7)

我们有一个tomcat服务器,垃圾收集持续约2分钟。最后,我们找到了原因,我们通过-Xmx为JVM分配了比系统上的物理内存更多的内存。这导致垃圾收集期间的分页,这会导致它被杀死。

此外,我们有多个VM在同一台物理计算机上运行。确保没有为所有VM分配比服务器上的物理内存更多的内存。

有关详细信息,请参阅Tuning the Memory Management System, section Setting the Heap Size(我的重点):

  

命令行选项:-Xms:-Xmx:

     

堆大小会影响分配速度和垃圾回收   频率和垃圾收集时间。一小堆就会变满   很快就必须更频繁地收集垃圾。它也很容易发生   更多碎片,使对象分配更慢。一大堆   在垃圾收集时间引入了一些轻微的开销。 一堆   大于系统中可用的物理内存必须   分页到磁盘,这导致访问时间长或甚至   应用程序冻结,尤其是在垃圾回收期间

答案 1 :(得分:1)

您正在使用并发垃圾收集器(-XX:+UseConcMarkSweepGC),它在一个单独的线程中运行。从您发布的Times输出看起来,垃圾收集器本身看起来并不长。我猜你的系统没有足够的CPU时间来运行GC,因此GC需要20秒才能获得所需的1秒CPU时间。使用并发GC时,应确保应用程序不会占用所有CPU时间。

否则会发生另一件事:如果并发收集器无法释放足够的内存并达到某个障碍,它将执行Full GC,它将阻止所有其他线程并消耗大量时间。这个Full GC的输出略有不同(说Full GC而不是GC),所以我想这不是你的问题。

答案 2 :(得分:0)

我认为这是在计算挂钟时间,所以如果其他进程中断GC并运行一段时间,那么这将被误报。

年轻一代不应该有任何导致收集需要很长时间的事情 - GC的成本与可到达项目的数量成正比,并且您的数字显示只有一小部分仍然可以到达。

参考队列管理和运行终结器可能占用大量时间,但不应该(??)计入该数量。

http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html有关于GC调整的提示。

答案 3 :(得分:0)

我只是偶然发现article说有大量方法可能导致长时间停顿(这是最后一节)摘录:

  

编译方法时,编译器生成并保存有关对象引用所在位置的信息(这有助于GC并称为oop map)大于特定大小的方法不会是JIT&#39;在热点中编辑。 ...如果该方法尚未进行JIT,则GC必须在GC期间自行生成oop映射。 ...大方法意味着生成oop贴图的大抽象解释时间。 ....顺便说一句,这个巨大的方法就像2500行一样,所以我称它为巨大的。

(插入粗体文字)