jvm的GC日志分析是怎樣的

這篇文章給大家介紹 jvm的GC日志分析是怎樣的,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

成都創(chuàng)新互聯(lián)公司成都企業(yè)網(wǎng)站建設(shè)服務(wù),提供成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)網(wǎng)站開發(fā),網(wǎng)站定制,建網(wǎng)站,網(wǎng)站搭建,網(wǎng)站設(shè)計(jì),成都響應(yīng)式網(wǎng)站建設(shè)公司,網(wǎng)頁設(shè)計(jì)師打造企業(yè)風(fēng)格網(wǎng)站,提供周到的售前咨詢和貼心的售后服務(wù)。歡迎咨詢做網(wǎng)站需要多少錢:13518219792

JVM的GC日志的主要參數(shù)包括如下幾個(gè):

-XX:+PrintGC 輸出GC日志

-XX:+PrintGCDetails 輸出GC的詳細(xì)日志

-XX:+PrintGCTimeStamps 輸出GC的時(shí)間戳(以基準(zhǔn)時(shí)間的形式)

-XX:+PrintGCDateStamps 輸出GC的時(shí)間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)

-XX:+PrintHeapAtGC 在進(jìn)行GC的前后打印出堆的信息

-XX:+PrintGCApplicationStoppedTime // 輸出GC造成應(yīng)用暫停的時(shí)間

-Xloggc:../logs/gc.log 日志文件的輸出路徑

常用JVM參數(shù)
分析gc日志后,經(jīng)常需要調(diào)整jvm內(nèi)存相關(guān)參數(shù),常用參數(shù)如下
-Xms:初始堆大小,默認(rèn)為物理內(nèi)存的1/64(<1GB);默認(rèn)(MinHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存小于40%時(shí),JVM就會增大堆直到-Xmx的最大限制
-Xmx:最大堆大小,默認(rèn)(MaxHeapFreeRatio參數(shù)可以調(diào)整)空余堆內(nèi)存大于70%時(shí),JVM會減少堆直到 -Xms的最小限制
-Xmn:新生代的內(nèi)存空間大小,注意:此處的大小是(eden+ 2 survivor space)。與jmap -heap中顯示的New gen是不同的。整個(gè)堆大小=新生代大小 + 老生代大小 + 永久代大小。 
在保證堆大小不變的情況下,增大新生代后,將會減小老生代大小。此值對系統(tǒng)性能影響較大,Sun官方推薦配置為整個(gè)堆的3/8。
-XX:SurvivorRatio:新生代中Eden區(qū)域與Survivor區(qū)域的容量比值,默認(rèn)值為8。兩個(gè)Survivor區(qū)與一個(gè)Eden區(qū)的比值為2:8,一個(gè)Survivor區(qū)占整個(gè)年輕代的1/10。
-Xss:每個(gè)線程的堆棧大小。JDK5.0以后每個(gè)線程堆棧大小為1M,以前每個(gè)線程堆棧大小為256K。應(yīng)根據(jù)應(yīng)用的線程所需內(nèi)存大小進(jìn)行適當(dāng)調(diào)整。在相同物理內(nèi)存下,減小這個(gè)值能生成更多的線程。但是操作系統(tǒng)對一個(gè)進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無限生成,經(jīng)驗(yàn)值在3000~5000左右。一般小的應(yīng)用, 如果棧不是很深, 應(yīng)該是128k夠用的,大的應(yīng)用建議使用256k。這個(gè)選項(xiàng)對性能影響比較大,需要嚴(yán)格的測試。和threadstacksize選項(xiàng)解釋很類似,官方文檔似乎沒有解釋,在論壇中有這樣一句話:"-Xss is translated in a VM flag named ThreadStackSize”一般設(shè)置這個(gè)值就可以了。
-XX:PermSize:設(shè)置永久代(perm gen)初始值。默認(rèn)值為物理內(nèi)存的1/64。
-XX:MaxPermSize:設(shè)置持久代最大值。物理內(nèi)存的1/4。

在我做了如下的設(shè)置

[java] view plain copy

 print?

  1. -XX:+PrintGCDetails -Xloggc:../logs/gc.log -XX:+PrintGCTimeStamps  

以后打印出來的日志為:

[java] view plain copy

 print?

  1. 0.756: [Full GC (System) 0.756: [CMS: 0K->1696K(204800K), 0.0347096 secs] 11488K->1696K(252608K), [CMS Perm : 10328K->10320K(131072K)], 0.0347949 secs] [Times: user=0.06 sys=0.00, real=0.05 secs]  

  2. 1.728: [GC 1.728: [ParNew: 38272K->2323K(47808K), 0.0092276 secs] 39968K->4019K(252608K), 0.0093169 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]  

  3. 2.642: [GC 2.643: [ParNew: 40595K->3685K(47808K), 0.0075343 secs] 42291K->5381K(252608K), 0.0075972 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]  

  4. 4.349: [GC 4.349: [ParNew: 41957K->5024K(47808K), 0.0106558 secs] 43653K->6720K(252608K), 0.0107390 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]  

  5. 5.617: [GC 5.617: [ParNew: 43296K->7006K(47808K), 0.0136826 secs] 44992K->8702K(252608K), 0.0137904 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]  

  6. 7.429: [GC 7.429: [ParNew: 45278K->6723K(47808K), 0.0251993 secs] 46974K->10551K(252608K), 0.0252421 secs]  

我們?nèi)〉箶?shù)第二條記錄分析一下各個(gè)字段都代表了什么含義

[java] view plain copy

 print?

  1. 5.617(時(shí)間戳): [GC(Young GC) 5.617(時(shí)間戳): [ParNew(GC的區(qū)域): 43296K(垃圾回收前的大?。?>7006K(垃圾回收以后的大小)(47808K)(該區(qū)域總大?。? 0.0136826 secs(回收時(shí)間)] 44992K(堆區(qū)垃圾回收前的大小)->8702K(堆區(qū)垃圾回收后的大?。?252608K)(堆區(qū)總大?。? 0.0137904 secs(回收時(shí)間)] [Times: user=0.03(GC用戶耗時(shí)) sys=0.00(GC系統(tǒng)耗時(shí)), real=0.02 secs(GC實(shí)際耗時(shí))]  

我們再對數(shù)據(jù)做一個(gè)簡單的分析

從最后一條GC記錄中我們可以看到 Young GC回收了 45278-6723=38555K的內(nèi)存

Heap區(qū)通過這次回收總共減少了 46974-10551=36423K的內(nèi)存。

38555-36423=2132K說明通過該次Young GC有2132K的內(nèi)存被移動到了Old Gen,

我們來驗(yàn)證一下

在最后一次Young GC的回收以前 Old Gen的大小為8702-7006=1696

回收以后Old Gen的內(nèi)存使用為10551-6723=3828

Old Gen在該次Young GC以后內(nèi)存增加了3828-1696=2132K 與預(yù)計(jì)的相符

[java] view plain copy

 print?

  1. 4.231: [GC 4.231: [DefNew: 4928K->512K(4928K), 0.0044047 secs] 6835K->3468K(15872K), 0.0045291 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]  

  2. 4.445: [Full GC (System) 4.445: [Tenured: 2956K->3043K(10944K), 0.1869806 secs] 4034K->3043K(15872K), [Perm : 3400K->3400K(12288K)], 0.1870847 secs] [Times: user=0.05 sys=0.00, real=0.19 secs]  

最前面的數(shù)字 4.231 和 4.445 代表虛擬機(jī)啟動以來的秒數(shù)。

[GC 和 [Full GC 是垃圾回收的停頓類型,而不是區(qū)分是新生代還是年老代,如果有 Full 說明發(fā)生了Stop-The-World 。如果是調(diào)用 System.gc() 觸發(fā)的,那么將顯示的是 [Full GC (System) 。

接下來的 [DefNew[Tenured[Perm 表示 GC 發(fā)生的區(qū)域,區(qū)域的名稱與使用的 GC 收集器相關(guān)。
Serial 收集器中新生代名為 “Default New Generation”,顯示的名字為 “[DefNew”。對于ParNew收集器,顯示的是 “[ParNew”,表示 “Parallel New Generation”。 對于 Parallel Scavenge 收集器,新生代名為 “PSYoungGen”。年老代和永久代也相同,名稱都由收集器決定。

方括號內(nèi)部顯示的 “4928K->512K(4928K)” 表示 “GC 前該區(qū)域已使用容量 -> GC 后該區(qū)域已使用容量 (該區(qū)域內(nèi)存總?cè)萘? ”。

再往后的 “0.0044047 secs” 表示該區(qū)域GC所用時(shí)間,單位是秒。

再往后的 “6835K->3468K(15872K)” 表示 “GC 前Java堆已使用容量 -> GC后Java堆已使用容量 (Java堆總?cè)萘浚薄?/p>

再往后的 “0.0045291 secs” 是Java堆GC所用的總時(shí)間。

最后的 “[Times: user=0.00 sys=0.00, real=0.00 secs]” 分別代表 用戶態(tài)消耗的CPU時(shí)間、內(nèi)核態(tài)消耗的CPU時(shí)間 和 操作從開始到結(jié)束所經(jīng)過的墻鐘時(shí)間。墻鐘時(shí)間包括各種非運(yùn)算的等待耗時(shí),如IO等待、線程阻塞。CPU時(shí)間不包括等待時(shí)間,當(dāng)系統(tǒng)有多核時(shí),多線程操作會疊加這些CPU時(shí)間,所以user或sys時(shí)間會超過real時(shí)間。

堆的分代

jvm的GC日志分析是怎樣的

  • young區(qū)域就是新生代,存放新創(chuàng)建對象;

  • tenured是年老代,存放在新生代經(jīng)歷多次垃圾回收后仍存活的對象;

  • perm是永生代,存放類定義信息、元數(shù)據(jù)等信息。

當(dāng)GC發(fā)生在新生代時(shí),稱為Minor GC,次收集;當(dāng)GC發(fā)生在年老代時(shí),稱為Major GC,主收集。 一般的,Minor GC的發(fā)生頻率要比Major GC高很多。

重新設(shè)置GC日志的輸出

[java] view plain copy

 print?

  1. -XX:+PrintGCDetails  

  2. -XX:+PrintHeapAtGC  

  3. -XX:+PrintGCDateStamps  

  4. -XX:+PrintTenuringDistribution  

  5. -verbose:gc  

  6. -Xloggc:gc.log  

后可以看到進(jìn)行GC前后的堆內(nèi)存信息 

[java] view plain copy

 print?

  1. {Heap before GC invocations=1 (full 0):  

  2.  PSYoungGen      total 152896K, used 131072K [0x00000000f5560000, 0x0000000100000000, 0x0000000100000000)  

  3.   eden space 131072K, 100% used [0x00000000f5560000,0x00000000fd560000,0x00000000fd560000)  

  4.   from space 21824K, 0% used [0x00000000feab0000,0x00000000feab0000,0x0000000100000000)  

  5.   to   space 21824K, 0% used [0x00000000fd560000,0x00000000fd560000,0x00000000feab0000)  

  6.  PSOldGen        total 349568K, used 0K [0x00000000e0000000, 0x00000000f5560000, 0x00000000f5560000)  

  7.   object space 349568K, 0% used [0x00000000e0000000,0x00000000e0000000,0x00000000f5560000)  

  8.  PSPermGen       total 26432K, used 26393K [0x00000000d0000000, 0x00000000d19d0000, 0x00000000e0000000)  

  9.   object space 26432K, 99% used [0x00000000d0000000,0x00000000d19c64a0,0x00000000d19d0000)  

  10. 2013-05-05T23:16:10.480+0800: 5.228: [GC  

  11. Desired survivor size 22347776 bytes, new threshold 7 (max 15)  

  12.  [PSYoungGen: 131072K->8319K(152896K)] 131072K->8319K(502464K), 0.0176346 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]   

  13. Heap after GC invocations=1 (full 0):  

  14.  PSYoungGen      total 152896K, used 8319K [0x00000000f5560000, 0x0000000100000000, 0x0000000100000000)  

  15.   eden space 131072K, 0% used [0x00000000f5560000,0x00000000f5560000,0x00000000fd560000)  

  16.   from space 21824K, 38% used [0x00000000fd560000,0x00000000fdd7ff78,0x00000000feab0000)  

  17.   to   space 21824K, 0% used [0x00000000feab0000,0x00000000feab0000,0x0000000100000000)  

  18.  PSOldGen        total 349568K, used 0K [0x00000000e0000000, 0x00000000f5560000, 0x00000000f5560000)  

  19.   object space 349568K, 0% used [0x00000000e0000000,0x00000000e0000000,0x00000000f5560000)  

  20.  PSPermGen       total 26432K, used 26393K [0x00000000d0000000, 0x00000000d19d0000, 0x00000000e0000000)  

  21.   object space 26432K, 99% used [0x00000000d0000000,0x00000000d19c64a0,0x00000000d19d0000)  

  22. }  

[java] view plain copy

 print?

  1. [0x00000000f5560000,0x00000000f5560000,0x00000000fd560000)  

這種形式的日志有兩種意義: 
當(dāng)這種日志出現(xiàn)在generation的詳細(xì)信息里的時(shí)候,三個(gè)數(shù)字在HotSpot里分別稱為low_boundary、high、high_boundary。 
low_boundary: reserved space的最低地址邊界;通常也跟“l(fā)ow”相等,這是commited space的最低地址邊界 
high: commited space的最高地址邊界 
high_boundary: reserved space的最高地址邊界。 

[low_boundary, high_boundary)范圍內(nèi)的就是reserved space,這個(gè)space的大小就是max capacity。 
[low, high)范圍內(nèi)的就是commited space,而這個(gè)space的大小就是current capacity(當(dāng)前容量),簡稱capacity。 
capacity有可能在一對最小值和最大值之間浮動。最大值就是上面說的max capacity。 

Gc日志分析工具

(1)GCHisto
http://java.net/projects/gchisto
直接點(diǎn)擊gchisto.jar就可以運(yùn)行,點(diǎn)add載入gc.log
統(tǒng)計(jì)了總共gc次數(shù),youngGC次數(shù),F(xiàn)ullGC次數(shù),次數(shù)的百分比,GC消耗的時(shí)間,百分比,平均消耗時(shí)間,消耗時(shí)間最小最大值等

(2)GCLogViewer
http://code.google.com/p/gclogviewer/
點(diǎn)擊run.bat運(yùn)行
整個(gè)過程gc情況的趨勢圖,還顯示了gc類型,吞吐量,平均gc頻率,內(nèi)存變化趨勢等
Tools里還能比較不同gc日志

關(guān)于 jvm的GC日志分析是怎樣的就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

標(biāo)題名稱:jvm的GC日志分析是怎樣的
路徑分享:http://bm7419.com/article4/ijppoe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、App設(shè)計(jì)網(wǎng)站內(nèi)鏈、商城網(wǎng)站、Google建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)