理解Java的GC日志


一、日志分析 
理解GC日志是處理Java虛擬機內存問題的基本技能,下面我們具體來看看。

通過在java命令種加入參數來指定對應的gc類型,打印gc日志信息並輸出至文件等策略。

1、編寫java代碼

  1. public class ReferenceCountingGC {
  2. public Object instance = null;
  3. private static final int ONE_MB = 1024 * 1024;
  4.  
  5. private byte[] bigSize = new byte[2 * ONE_MB];
  6.  
  7. public static void main(String[] args) {
  8. testGC();
  9.  
  10.  
  11. }
  12.  
  13. public static void testGC() {
  14. ReferenceCountingGC objA = new ReferenceCountingGC();
  15. ReferenceCountingGC objB = new ReferenceCountingGC();
  16. objA.instance = objB;
  17. objB.instance = objA;
  18.  
  19. objA = null;
  20. objB = null;
  21.  
  22. System.gc();
  23. }
  24. }

2、編譯java文件

javac ReferenceCountingGC.java 
  • 1

3、執行class文件

java -XX:+PrintGCDateStamps -XX:+PrintGCDetails ReferenceCountingGC
  • 1

對應的參數列表

  1. -XX:+PrintGC 輸出GC日志
  2. -XX:+PrintGCDetails 輸出GC的詳細日志
  3. -XX:+PrintGCTimeStamps 輸出GC的時間戳(以基准時間的形式)
  4. -XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800
  5. -XX:+PrintHeapAtGC 在進行GC的前后打印出堆的信息
  6. -Xloggc:../logs/gc.log 日志文件的輸出路徑
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

結果輸出:

  1. 2016-03-20T14:34:55.118-0800: [GC [PSYoungGen: 6123K->400K(38912K)] 6123K->400K(125952K), 0.0012070 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
  2. 2016-03-20T14:34:55.119-0800: [Full GC [PSYoungGen: 400K->0K(38912K)] [ParOldGen: 0K->282K(87040K)] 400K->282K(125952K) [PSPermGen: 2622K->2621K(21504K)], 0.0084640 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
  3. Heap
  4. PSYoungGen total 38912K, used 1013K [0x00000007d5500000, 0x00000007d8000000, 0x0000000800000000)
  5. eden space 33792K, 3% used [0x00000007d5500000,0x00000007d55fd7d0,0x00000007d7600000)
  6. from space 5120K, 0% used [0x00000007d7600000,0x00000007d7600000,0x00000007d7b00000)
  7. to space 5120K, 0% used [0x00000007d7b00000,0x00000007d7b00000,0x00000007d8000000)
  8. ParOldGen total 87040K, used 282K [0x0000000780000000, 0x0000000785500000, 0x00000007d5500000)
  9. object space 87040K, 0% used [0x0000000780000000,0x0000000780046bf8,0x0000000785500000)
  10. PSPermGen total 21504K, used 2628K [0x000000077ae00000, 0x000000077c300000, 0x0000000780000000)
  11. object space 21504K, 12% used [0x000000077ae00000,0x000000077b091380,0x000000077c300000)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

PSYoungGen表示新生代,這個名稱由收集器決定,這里的收集器是Parallel Scavenge。老年代為ParOldGen,永久代為PSPermGen 
如果收集器為ParNew收集器,新生代為ParNew,Parallel New Generation 
如果收集器是Serial收集器,新生代為DefNew,Default New Generation

可以看到上面有兩種GC類型:GC和Full GC,有Full表示這次GC是發生了Stop-The-World的。

新生代GC(Minor GC):指發生在新生代的垃圾收集動作,因為Java對象大多都具備朝生夕滅的特性,所以Minor GC非常頻繁,一般回收速度非常快。

老年代GC(Major GC/Full GC):指發生在老年代的GC,出現了Major GC,經常會伴隨至少一次的Minor GC,Major GC的速度一般會比Minor GC慢10倍以上。

[GC [PSYoungGen: 6123K->400K(38912K)] 6123K->400K(125952K), 0.0012070 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

上面方括號內部的6123K->400K(38912K),表示GC前該內存區域已使用容量->GC后該內存區域已使用容量,后面圓括號里面的38912K為該內存區域的總容量。

方括號外面的6123K->400K(125952K),表示GC前Java堆已使用容量->GC后Java堆已使用容量,后面圓括號里面的125952K為Java堆總容量。

[Times: user=0.00 sys=0.00, real=0.00 secs]分別表示用戶消耗的CPU時間,內核態消耗的CPU時間和操作從開始到結束所經過的牆鍾時間(Wall Clock Time),CPU時間和牆鍾時間的差別是,牆鍾時間包括各種非運算的等待耗時,例如等待磁盤I/O、等待線程阻塞,而CPU時間不包括這些耗時。

二、GC日志的離線分析

可以使用一些離線的工具來對GC日志進行分析,比如sun的gchisto( https://java.net/projects/gchisto),gcviewer( https://github.com/chewiebug/GCViewer ),這些都是開源的工具,用戶可以直接通過版本控制工具下載其源碼,進行離線分析。

 

 https://blog.csdn.net/u014756827/article/details/78227556


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM