- 45.152: [GC [PSYoungGen: 295648K->32968K(306432K)] 296198K->33518K(1006848K), 0.1083183 secs][Times: user=1.83 sys=0.01, real=0.11 secs]
45.152是表明距離JVM啟動到垃圾回收的秒數(shù),GC標(biāo)簽表明是Minor GC或者young代垃圾回收。
[PSYoungGen: 295648K->32968K(306432K)]提供了young代的空間信息,PSYoungGen表示young代的垃圾回收是使用throughput垃圾回收器。其他可能的young代垃圾回收有ParNew(使用CMS垃圾回收器多線程回收young代空間)、DefNew(使用serial垃圾回收器單線程回收young代空間)。
在“->”左邊的數(shù)字(295648K)表示垃圾回收前young代的空間大小,右邊數(shù)字(32968K)表示垃圾回收后的young代空間大小。young代被分為eden區(qū)域和survivor區(qū)域。由于在垃圾回收之后,eden區(qū)域是空的,右邊的數(shù)字其實(shí)就是survivor區(qū)域的空間。在括號里面的數(shù)字(306432K)表示young代的總空間。
296198K->33518K(1006848K)提供了Java堆在垃圾回收前后的使用情況。另外,他提供Java堆的總大小,是young代和old代的和。在->左邊的數(shù)字(296198K)表示,在垃圾回收前Java堆占用的空間,->右邊的數(shù)字(33518K)表示垃圾回收后Java堆占用空間。括號里面的數(shù)字(1006848K)表示Java堆總共的空間。
通過young代的占用空間和Java堆占用的空間,可以快速的計算出old代占用的空間。比如:Java堆的大小是1006848K,young代的空間大小是306432K,因此可以計算出old代的空間大小是1006848K-306432K=700416K。在垃圾回收之前,296198K-295648K=550K是old代使用了的空間。在垃圾回收后33518K-32968K=550K。在這個例子中,在垃圾回收前后沒有對象從young代移動到old代。這是一個重要的觀察說明了Minor GC回收原則。如果有對象被移動到old代,然后變成不可讀取的,就不是最大量的對象被回收,會違反Minor GC回收原則。
0.1083183 secs表明垃圾回收執(zhí)行的時間。
[Times: user=1.83 sys=0.01, real=0.11 secs]提供了CPU和占用時間。user表明垃圾回收在用戶模式下執(zhí)行消耗的CPU時間,即:在JVM里面運(yùn)行的時間,在這個例子中,垃圾回收器在用戶模式下消耗1.83秒的CPU時間。sys表示操作系統(tǒng)代表垃圾回收器消耗的時間,在這里例子中,垃圾回收器使用0.01秒的操作系統(tǒng)CPU時間。real表示垃圾回收執(zhí)行的時間的。這幾個數(shù)字精確到0.01秒。
如果你對垃圾回收的實(shí)際時間感興趣,可以設(shè)置-XX:+PrintGCDateStamps選項(xiàng)。-XX:+PrintGCDateStamps顯示垃圾回收發(fā)生的年,月,日和時間。這個選項(xiàng)是在Java 6 Update 4引入的。下面的例子是同時使用-XX:+PrintGCDateStamps和-XX:+PrintGCDetails選項(xiàng)的結(jié)果:
- 2012-06-21T09:57:10.518-0500: [GC[PSYoungGen: 295648K->32968K(306432K)]296198K->33518K(1006848K), 0.1083183 secs][Times: user=1.83 sys=0.01, real=0.11 secs]
2012-06-21T09:57:10.518-0500字段是使用了ISO 8601日期和時間戳。格式是YYYY-MM-DDTHH-MM-SS.mmm-TZ,分別的意思是:
YYYY表示4位數(shù)的年
MM表示2位數(shù)月,如果只有一位數(shù),前面加0
DD表示2位數(shù)的天,如果只有一位數(shù),前面加0
T是一個字符用來隔開日期和時間
HH表示2位數(shù)小時,如果只有一位數(shù),前面加0
MM表示2位數(shù)分鐘,如果只有一位數(shù),前面加0
SS表示2位數(shù)秒,如果只有一位數(shù),前面加0
mmm表示3位數(shù)毫秒,如果不足三位,前面加0或者00
TZ表示格林尼治時間的時區(qū)
盡管時區(qū)已經(jīng)包含在輸出里面了,但是輸出日期和時間不是GMT時間,而是本地化過的時間。
當(dāng)為了低延遲而優(yōu)化HotSpot VM的時候,下面的兩個選項(xiàng)是非常有用的,這兩個選項(xiàng)會報告應(yīng)用由于虛擬機(jī)的安全點(diǎn)(Safepoint)操作而阻塞的時間以及應(yīng)用程序在安全點(diǎn)(Safepoint)執(zhí)行了多長的時間。
- -XX:+PrintGCApplicationStoppedTime
- -XX:+PrintGCApplicationConcurrentTime
安全點(diǎn)(Safepoint)操作會讓JVM進(jìn)入一種所有應(yīng)用程序的線程都被阻塞以及阻止任何正在執(zhí)行的本地程序把結(jié)果返回給Java代碼的狀態(tài)。當(dāng)需要進(jìn)行優(yōu)化虛擬機(jī)內(nèi)部操作的時候,安全點(diǎn)(Safepoint操作會被執(zhí)行以使得所有線程都進(jìn)入阻塞狀態(tài)避免影響Java堆(垃圾回收是一種安全點(diǎn)(Safepoint操作)。
由于安全點(diǎn)(Safepoint)操作阻塞了所有Java程序的執(zhí)行,所以知道程序的響應(yīng)時間延遲是否和安全點(diǎn)(Safepoint)操作有關(guān)系就顯得非常重要了。因此,能夠觀察程序什么時候被阻塞( 通過設(shè)置-XX:+PrintGCApplicationStoppedTime選項(xiàng))通過應(yīng)用的日志信息能夠幫組你識別出,當(dāng)應(yīng)用的響應(yīng)時間超過預(yù)期的時候,是安全點(diǎn)(Safepoint)操作引起的還是應(yīng)用或者操作系統(tǒng)的其他操作引起的。-XX:+PrintSafepointStatistics可以幫助區(qū)別垃圾回收的安全點(diǎn)(Safepoint)以及其他的安全點(diǎn)(Safepoint)。
在發(fā)現(xiàn)應(yīng)用的響應(yīng)時間超過預(yù)期的預(yù)期的時候,-XX:+PrintGCApplicationConcurrentTime選項(xiàng)可以用來判斷程序是否被執(zhí)行以及執(zhí)行了多長時間。
下圖總結(jié)了前面提到的垃圾回收器的選項(xiàng)以及給出了使用它們的合適情況。