jvm系列(九):Java GC 分析

轉自:https://www.cnblogs.com/ityouknow/p/7550068.htmlhtml

Java GC就是JVM記錄儀,書畫了JVM各個分區的表演。java

 

什麼是 Java GC

Java GC(Garbage Collection,垃圾收集,垃圾回收)機制,是Java與C++/C的主要區別之一,做爲Java開發者,通常不須要專門編寫內存回收和垃圾清理代碼,對內存泄露和溢出的問題,也不須要像C程序員那樣戰戰兢兢。這是由於在Java虛擬機中,存在自動內存管理和垃圾清掃機制。歸納地說,該機制對JVM(Java Virtual Machine)中的內存進行標記,並肯定哪些內存須要回收,根據必定的回收策略,自動的回收內存,永不停息(Nerver Stop)的保證JVM中的內存空間,防止出現內存泄露和溢出問題。程序員

在Java語言出現以前,就有GC機制的存在,如Lisp語言),Java GC機制已經日臻完善,幾乎能夠自動的爲咱們作絕大多數的事情。然而,若是咱們從事較大型的應用軟件開發,曾經出現過內存優化的需求,就一定要研究Java GC機制。web

簡單總結一下,Java GC就是經過GC收集器回收不在存活的對象,保證JVM更加高效的運轉。若是不瞭解GC算法和垃圾回收器能夠參考這篇文章:jvm系列(三):GC算法 垃圾收集器算法

 

如何獲取 Java GC日誌

通常狀況能夠經過兩種方式來獲取GC日誌,一種是使用命令動態查看,一種是在容器中設置相關參數打印GC日誌。tomcat

命令動態查看

Java 自動的工具行命令,jstat能夠用來動態監控JVM內存的使用,統計垃圾回收的各項信息。bash

好比經常使用命令,jstat -gc 統計垃圾回收堆的行爲併發

$ jstat -gc 1262
 S0C    S1C     S0U     S1U   EC       EU        OC         OU        PC       PU         YGC    YGCT    FGC    FGCT     GCT   
26112.0 24064.0 6562.5  0.0   564224.0 76274.5   434176.0   388518.3  524288.0 42724.7    320    6.417   1      0.398    6.815

也能夠設置間隔固定時間來打印:less

$ jstat -gc 1262 2000 20

這個命令意思就是每隔2000ms輸出1262的gc狀況,一共輸出20次jvm

更詳細的內容參考這篇文章:jvm系列(四):jvm調優-命令篇

 

GC參數

JVM的GC日誌的主要參數包括以下幾個:

  • -XX:+PrintGC 輸出GC日誌
  • -XX:+PrintGCDetails 輸出GC的詳細日誌
  • -XX:+PrintGCTimeStamps 輸出GC的時間戳(以基準時間的形式)
  • -XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2017-09-04T21:53:59.234+0800)
  • -XX:+PrintHeapAtGC 在進行GC的先後打印出堆的信息
  • -Xloggc:../logs/gc.log 日誌文件的輸出路徑

在生產環境中,根據須要配置相應的參數來監控JVM運行狀況。

 

Tomcat 設置示例

咱們常常在tomcat的啓動參數中添加JVM相關參數,這裏有一個典型的示例:

JAVA_OPTS="-server -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m -XX:SurvivorRatio=4 -verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log -Djava.awt.headless=true -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000 -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15"

根據上面的參數咱們來作一下解析:

  • -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m -XX:MaxPermSize=256m
    Xms,即爲jvm啓動時得JVM初始堆大小,Xmx爲jvm的最大堆大小,xmn爲新生代的大小,permsize爲永久代的初始大小,MaxPermSize爲永久代的最大空間。

  • -XX:SurvivorRatio=4
    SurvivorRatio爲新生代空間中的Eden區和救助空間Survivor區的大小比值,默認是8,則兩個Survivor區與一個Eden區的比值爲2:8,一個Survivor區佔整個年輕代的1/10。調小這個參數將增大survivor區,讓對象儘可能在survitor區呆長一點,減小進入年老代的對象。去掉救助空間的想法是讓大部分不能立刻回收的數據儘快進入年老代,加快年老代的回收頻率,減小年老代暴漲的可能性,這個是經過將-XX:SurvivorRatio 設置成比較大的值(好比65536)來作到。

  • -verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log
    將虛擬機每次垃圾回收的信息寫到日誌文件中,文件名由file指定,文件格式是平文件,內容和-verbose:gc輸出內容相同。

  • -Djava.awt.headless=true
    Headless模式是系統的一種配置模式。在該模式下,系統缺乏了顯示設備、鍵盤或鼠標。

  • -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
    設置gc日誌的格式

  • -Dsun.rmi.dgc.server.gcInterval=600000 -Dsun.rmi.dgc.client.gcInterval=600000
    指定rmi調用時gc的時間間隔

  • -XX:+UseConcMarkSweepGC -XX:MaxTenuringThreshold=15
    採用併發gc方式,通過15次minor gc 後進入年老代

 

如何分析GC日誌

摘錄GC日誌一部分

Young GC回收日誌:

2016-07-05T10:43:18.093+0800: 25.395: [GC [PSYoungGen: 274931K->10738K(274944K)] 371093K->147186K(450048K), 0.0668480 secs] [Times: user=0.17 sys=0.08, real=0.07 secs]

Full GC回收日誌:

2016-07-05T10:43:18.160+0800: 25.462: [Full GC [PSYoungGen: 10738K->0K(274944K)] [ParOldGen: 136447K->140379K(302592K)] 147186K->140379K(577536K) [PSPermGen: 85411K->85376K(171008K)], 0.6763541 secs] [Times: user=1.75 sys=0.02, real=0.68 secs]

經過上面日誌分析得出,PSYoungGen、ParOldGen、PSPermGen屬於Parallel收集器。其中PSYoungGen表示gc回收先後年輕代的內存變化;ParOldGen表示gc回收先後老年代的內存變化;PSPermGen表示gc回收先後永久區的內存變化。young gc 主要是針對年輕代進行內存回收比較頻繁,耗時短;full gc 會對整個堆內存進行回城,耗時長,所以通常儘可能減小full gc的次數

經過兩張圖很是明顯看出gc日誌構成:

Young GC日誌:

Full GC日誌:

 

GC分析工具

 

GChisto

GChisto是一款專業分析gc日誌的工具,能夠經過gc日誌來分析:Minor GC、full gc的時間、頻率等等,經過列表、報表、圖表等不一樣的形式來反應gc的狀況。雖然界面略顯粗糙,可是功能仍是不錯的。

配置好本地的jdk環境以後,雙擊GChisto.jar,在彈出的輸入框中點擊 add 選擇gc.log日誌

  • GC Pause Stats:能夠查看GC 的次數、GC的時間、GC的開銷、最大GC時間和最小GC時間等,以及相應的柱狀圖

  • GC Pause Distribution:查看GC停頓的詳細分佈,x軸表示垃圾收集停頓時間,y軸表示是停頓次數。

  • GC Timeline:顯示整個時間線上的垃圾收集

不過這款工具已經再也不維護

 

GC Easy

這是一個web工具,在線使用很是方便.

地址: http://gceasy.io

進入官網,講打包好的zip或者gz爲後綴的壓縮包上傳,過一會就會拿到分析結果。

推薦使用此工具進行gc分析。

相關文章
相關標籤/搜索