1. 程式人生 > >JVM調優、GC總結

JVM調優、GC總結

最大和 循環 cut cap bili 內存區域 stack adc 引入

  • 內存分配
    http://blog.csdn.net/shimiso/article/details/8595564
    http://blog.csdn.net/OyangYujun/article/details/41173747

  • 特殊的內存:非JVM規範的內存區域:直接內存
    直接內存並不是虛擬機規範定義的數據區的一部分,也不是虛擬機運行時數據區的一部分。但是這部分內存也被頻繁的使用,而且也可能導致OOM。
    在JDK1.4中新加入了NIO類,引入了一種基於通道與緩沖區的I/O方式。它可以使用Native函數庫直接分配堆外內存,然後通過一個存儲在Java堆中的DirectByteBuffer對象作為這塊內存的引用進行操作。這樣能在一些場合中顯著提高性能,因為避免了在Java堆和Native堆中來回復制數據。

  • 內存模型
    http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html

判斷對象是否存活一般有兩種方式:
1. 引用計數:每個對象有一個引用計數屬性,新增一個引用時計數加1,引用釋放時計數減1,計數為0時可以回收。此方法簡單,無法解決對象相互循環引用的問題。
2. 可達性分析(Reachability Analysis):從GC Roots開始向下搜索,搜索所走過的路徑稱為引用鏈。當一個對象到GC Roots沒有任何引用鏈相連時,則證明此對象是不可用的。不可達對象。

JVM垃圾回收機制采用有向圖方式來管理內存中的對象  
    • 對象在內存中的狀態:可達狀態、可恢復狀態、不可達狀態

      • 可達狀態:對象被創建後,有一個以上的引用變量引用它時。
      • 可恢復狀態:如果對象不再有任何引用變量引用它,將先進入可恢復狀態,此時不能從有向圖頂點導航到該對象,系統垃圾回收機制準備回收內存,在回收之前系統將調用可恢復狀態的對象的finalize方法進行資源清理,若finalize方法能讓一個以上的變量引用此對象,則對象會再次變為可達狀態,否則進入不可達狀態。
      • 不可達狀態:當對象所有聯系都被切斷,且finalize方法沒有使該對象變成可達,則對象將永久失去引用。系統會進行回收。
    • Java對對象的引用分4種:強引用、軟引用、弱引用、虛引用。

      • 強引用:創建變量並引用;最常用;絕對不會被垃圾回收機制回收,即使內存非常緊張。
      • 軟引用:SoftReference;當系統內存足夠時不會被系統回收,當系統內存空間不足時,系統將會回收;常用於創建大量某類對象時做優化;
      • 弱引用:WeakReference;當系統垃圾回收時,不管系統內存夠不夠,總會回收該對象所占內存;
      • 虛引用:不可單獨使用,一般配合引用隊列使用;主要作用是跟蹤對象被垃圾回收的狀態,程序可以通過檢查與虛引用關聯的引用隊列中是否已經包含指定虛引用,從而了解虛引用的對象是否即將被回收。
    • Java常用調試工具和命令

      • 1、jps
        顯示系統中所有Hotspot虛擬機進程。
        參數:
        -l :輸出主類全名。
        -v:輸出虛擬機進程啟動的jvm參數。
        -m:輸出啟動時傳遞給main函數的參數。
        -q:只輸出LVMID,省略主類的名稱。

      • 2、jinfo
        顯示虛擬機的配置信息,可觀察進程運行環境參數,包括Java System屬性和JVM命令行參數。
        參數:
        -flag< name >: 打印指定Java虛擬機的參數值。
        -flag [+|-]< name >:設置或取消指定java虛擬機參數的布爾值。
        -flag < name >=< value >:設置指定java虛擬機的參數的值。
        示例:
        ? ~ jinfo 10565
        ? ~ jinfo -flag CICompilerCount 10565
        ? ~ jinfo -flag +PrintGCDetails
        ? ~ jinfo -flag -PrintGCDetails 10532
        ? ~ jinfo -flag CMSInitiatingOccupancyFraction=80 10532

      • 3、jstack
        作用:
        顯示虛擬機的線程棧信息,用於生成當前JVM的所有線程快照。
        參數:
        -F:當正常輸出的請求不被響應時,強制輸出線程堆棧。
        -l:除堆棧外,顯示關於鎖的附加信息。
        -m:如果調用到本地方法的話,可以顯示C/C++的堆棧
        命令格式:jstack [option] vmid。 示例:
        ? ~ jstack -F 10532
        ? ~ jstack -l 10532
        ? ~ jstack -m 10532

      • 4、jstat
        作用:
        實時顯示本地或遠程JVM進程中類裝載、內存、垃圾收集、JIT編譯等數據。
        參數:
        -class:監視類裝載、卸載數量、總空間及類裝載所耗費的時間。
        -gc:監聽Java堆狀況,包括Eden區、兩個Survivor區、老年代、永久代等的容量,以用空間、GC時間合計等信息。
        -gccapacity:監視內容與-gc基本相同,但輸出主要關註java堆各個區域使用到的最大和最小空間。
        -gcutil:監視內容與-gc基本相同,但輸出主要關註已使用空間占總空間的百分比。
        -gccause:與-gcutil功能一樣,但是會額外輸出導致上一次GC產生的原因。
        -gcnew:監視新生代GC狀況。
        -gcnewcapacity:監視內同與-gcnew基本相同,輸出主要關註使用到的最大和最小空間。
        -gcold:監視老年代GC情況。
        -gcoldcapacity:監視內同與-gcold基本相同,輸出主要關註使用到的最大和最小空間。
        -gcpermcapacity:輸出永久代使用到最大和最小空間。
        -compiler:輸出JIT編譯器編譯過的方法、耗時等信息。
        -printcompilation:輸出已經被JIT編譯的方法。
        示例:
        ? ~ jstat -class 10532
        ? ~ jstat -gc 10532
        ? ~ jstat -gccapacity 10532
        ? ~ jstat -gcutil 10532
        ? ~ jstat -gccause 10532
        ? ~ jstat -gcnew 10532
        ? ~ jstat -gcnewcapacity 10532
        ? ~ jstat -gcold 10532
        ? ~ jstat -gcoldcapacity 10532
        ? ~ jstat -compiler 10532
        ? ~ jstat -printcompilation 10532

      • 5、jmap、jhat
        作用:
        用於生成虛擬機的內存快照信息
        jhat用網頁方式查看dump信息
        參數:
        -dump:生成java堆轉儲快照。
        -heap:顯示java堆詳細信息(只在Linux/Solaris下有效)。
        -F:當虛擬機進程對-dump選項沒有響應時,可使用這個選項強制生成dump快照(只在linux/Solaris下有效)。
        -finalizerinfo:顯示在F-Queue中等待Finalizer線程執行finalize方法的對象(只在Linux/Solaris下有效)。
        -histo:顯示堆中對象統計信息。
        -permstat:以ClassLoader為統計口徑顯示永久代內存狀態(只在Linux/Solaris下有效)。
        示例:
        ? ~ jmap -heap 10532
        ? ~ jmap -histo 10532 | more
        ? ~ jmap -F 10532 ? ~ jmap -finalizerinfo 10532

      • 6、jconsole
        作用:
        內置 Java 性能分析器,可以從命令行或在 GUI shell 中運行。可使用 JConsole來監控 Java 應用程序性能和跟蹤 Java 中的代碼。

      • 7、gc相關術語
        S0C:S0區容量(S1區相同,略)
        S0U:S0區已使用
        EC:E區容量
        EU:E區已使用
        OC:老年代容量
        OU:老年代已使用
        PC:Perm容量
        PU:Perm區已使用
        YGC:Young GC(Minor GC)次數
        YGCT:Young GC總耗時
        FGC:Full GC次數
        FGCT:Full GC總耗時
        GCT:GC總耗時

    • jvm參數調優 各個參數意義
      http://www.cnblogs.com/andy-zhou/p/5327288.html
      http://www.cnblogs.com/edwardlauxh/archive/2010/04/25/1918603.html
      http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
      http://blog.csdn.net/rongbo_j/article/details/51107898

    • GC算法
      http://www.cnblogs.com/ityouknow/p/5614961.html
      http://blog.csdn.net/lingzhm/article/details/47174391

    • classloader 委派模型

    • 類加載器產生泄露原因總結。
      1、永久代內存不足
      2、動態代理類生成大量類

    • 定義自已的類加載器分為兩步:
      1、繼承java.lang.ClassLoader
      2、重寫父類的findClass方法

      為什麽只重寫findClass方法?
      因為JDK已經在loadClass方法中幫我們實現了ClassLoader搜索類的算法,當在loadClass方法中搜索不到類時,loadClass方法就會調用findClass方法來搜索類,所以我們只需重寫該方法即可。如沒有特殊的要求,一般不建議重寫loadClass搜索類的算法。

JVM調優、GC總結