本文摘自《Java性能优化权威指南》第7章“JVM性能调优入门”,这一章介绍了一些非常实用的调优技巧。本文节选的是正文里穿插的一个小TIP。


如果修改老年代空间大小后,只观察到Full GC,很可能是老年代与新生代空间大小失去了平衡,导致应用程序只进行Full GC。这一情况通常缘于即使经过Full GC,老年代空间仍不足以容纳所有从新生代提升的对象。通过GC统计日志中的以下信息可以确认这种问题:

  2010-12-06T15:10:11.231-0800: [Full GC 
      [PSYoungGen: 196608K->146541K(229376K)] 
      [ParOldGen: 262142K->262143K(262144K)] 
      458750K->408684K(491520K) 
      [PSPermGen: 26329K->26329K(32768K)], 
      17.0440216 secs] 
      [Times: user=11.03 sys=0.11, real=17.04 secs] 
  2010-12-05T15:10:11.853-0800: [Full GC 
      [PSYoungGen: 196608K->148959K(229376K)] 
      [ParOldGen: 262143K->262143K(262144K)] 
      458751K->411102K(6291456K) 
      [PSPermGen: 26329K->26329K(32768K)], 
      18.1471123 secs] 
      [Times: user=12.13 sys=0.12, real=18.15 secs]
  2010-12-05T15:10:12.099-0800: [Full GC 
      [PSYoungGen: 196608K->150377K(229376K)] 
      [ParOldGen: 262143K->262143K(262144K)] 
      458751K->412520K(6291456K) 
      [PSPermGen: 26329K->26329K(32768K)], 
      17.8130416 secs] 
      [Times: user=11.97 sys=0.12, real=17.81 secs]

标识老年代空间不够大的一个线索是每次Full GC后,老年代中几乎没有任何空间被回收(ParOldGen标识右边的值)于此同时,新生代中总有大量的对象占用空间。当老年代中空间无法接纳从新生代中提升的对象时,正如我们在上面的输出中观察到的,这些对象会被“退还”(Back Up)到新生代空间中。

《Java性能优化权威指南》的边边角(2)——理解JVM-系统锁

《Java性能优化权威指南》的边边角(3)——生存代和内存泄漏

《Java性能优化权威指南》的边边角(4)——封面吉祥物Duke

《Java性能优化权威指南》的边边角(5)——被我们搬运的豆瓣读书笔记