java代碼的執行機制+JVM+GC

1.java源碼編譯機制

1.1 分析和輸入到符號表(Parse and Enter)
    Parse:詞法和語法分析
    Enter:將符號輸入到符號表

1.2 註解處理(Annotation Processing)
    處理用戶自定義的annotation

1.3 語義分析和生成class(Analyse and  Generate)
    Analyse:基於抽象語法樹進行一系列的語義分析
    Generate:生成class,實例-》構造器、靜態成員-》<clinit>、抽象語法樹-》字節碼(後序便利語法樹)、最少代碼轉換。

class文件中包含的信息
*結構信息
*元數據
*方法信息

2.類加載機制
    指.class文件加載到JVM中,並造成Class對象的機制。
    能夠在運行時動態加載.class

*裝載(Load)-》連接(link){ 校驗(Verify)->準備(Prepare)->解析(Resolve)可選操做}-》初始化(Initialize)

2.1 裝載(Load)
    找到二進制字節碼並加載到JVM中(標識:類的全限定名+ClassLoader實例ID)

2.2 連接(Link)
    對二進制字節碼的格式進行校驗、初始化靜態變量、解析類中的藉口、類。

2.3 初始化(Initialize)
    執行類中的靜態初始化代碼、構造器代碼以及靜態屬性。

2.4 JVM類加載經過ClassLoader及其子類來完成
(加載順序由上到下)

BootStrap  Class Loader  ->SJAVAHOME/jre/Lib/rt.jar
^
Extension Class Loader ->SJAVAHOME/jre/lib/ext/*.jar
(對應類名:ExtClassLoader)
^
System Class Loader -> SCLASSPATH
(對應類名:AppClassLoader)
^
User-Defined Class Loader
(開發人員繼承ClassLoader自行實現的ClassLoader)
sati
類加載器委託機制:由最上面的類加載器開始加載類

3.JVM內存管理

方法區、堆、本地方法棧、PC寄存器、JVM方法棧

3.1 方法區
存放:類的信息(名稱、修飾符等)、靜態變量、final、Field、類中方法信息。
內存超過:OutOfMemory
大小調整
-XX:PermSize    最小值
-XX:MaxPermSize    最大值

3.2
存放:對象實例、數組值,new出來的對象
32位操做系統最大2G
-Xms    JVM啓動時最小Heap內存
-Xmx     JVM啓動時最大Heap內存
一般設置 -Xms 等於 -Xmx
-XX:MinHeapFreeRatio    當空餘堆內存小於 40% 會增長到 -Xmx
-XX:MaxHeapFreeRatio     當空餘堆內存大於 70% 會減少到 -Xms

-Xmn    新生代的大小
-XX:SurvivorRatio    調整Eden Space、Survivor Space的大小
-XX:PretenureSizeThreshold=1024    (單位字節,默認0)表明對象超過多大就不在新生代分配,而是直接在舊生代分配

舊生代內存 -Xmx 減去 -Xmn

3.3 本地方法棧
存放:每一個native方法調用的狀態

3.4 PC寄存器和JVM方法棧
存放:線程(每一個線程會建立PC寄存器和JVM方法棧)
PC寄存器佔用CPU寄存器或操做系統內存
JVM方法棧佔用操做系統內存
JVM方法棧空間不足:StackOverflowError

-Xss    指定JVM方法棧大小


-XX:TLABWasteTargetPercent    設置TLAB 可佔用Eden Space 的百分比,默認爲1%
TLAB(Thread Local Allocation Buffer)

啓動參數上增長
-XX:+PrintTLAB    查看TLAB空間的使用狀況


-XX:SoftRefLRUPolicyMB    softReference(軟引用)的存活時間,默認爲1秒

-XX:MaxTenuringThreshold    在串行和ParNew方式時可設置,Minor GC中存活的次數爲多少,才放入到舊生代

4. Sun JDK 中可用的GC

4.1 新生代可用GC

4.1.1 Serial GC (串行GC)
    整個掃描和複製都是單線程方式進行
-XX:+UseSerialGC     強制指定用此方法回收GC

4.1.2 Parallel Scavenge (並行回收GC)
    在多CPU的機器上採用多線程回收
-XX:InitialSurvivorRatio    設置Eden、S0、S1的比例劃分、默認爲8
jdk1.6後採用 -XX:SurvivorRatio

-XX:-UseAdaptiveSizePolicy    固定Eden、S0、S1的大小

-XX:+UseParallelGC    強制指定用此方法回收GC
-XX:ParallelGCThreads    強制指定線程數

4.1.3 ParNew (並行GC)
在配置爲CMS GC的狀況下,新生代默認採用並行GC方式
-XX:+UseParNewGC    強制指定

-XX:+DisableExplicitGC    禁止程序中調用System.gc 觸發GC

4.2 舊生代可用的GC

4.2.1 串行

-XX:+PrintGCApplicationStoppedTime    查看GC形成的應用暫停的時間

5.異常
1.舊生代空間不足
java.lang.OutOfMemoryError: Java heap space

2.Permanet Generation 空間滿
java.lang.OutOfMemoryError: PermGen space

3.CMS GC出現 Promotion failed 和 concurrent mode failure
增大survivor space、舊生代空間或調低觸發兵法GC的比率
-XX: CMS MaxAbortablePrecleanTime=5 (單位爲ms)避免CMS在remark完畢後好久才觸發sweeping動做

啓動時設置FullGC的執行間隔時間
-java -Dsum.rmi.dgc.client.gcInterval=3600000
禁止RMI調用 System.gc
-XX:+DisableExplicitGC

Sun JDK 提供兩種簡單方式如今GC
-XX:GCTimeRatio=n    設置JVM GC策略(吞吐量優先
-XX:MaxGCPauseMillis=n    設置JVM GC策略(暫停時間優先

6.新內容GC
Garbage First 簡稱G1:減小GC所致使的應用暫停時間,同時保持JVM堆空間的利用率

7.Real-Time JDK
1.新內存管理機制
Immortal、Scoped內存區域,均不受GC管理,基於這兩個內存區域來編寫應用徹底不用擔憂GC會形成的暫停現象。

2.容許Java應用直接訪問物理內存
不須要勇敢native code才能訪問,能訪問物理內存,直接將對象放入物理內存,而非JVM heap中。

8.JVM內存查看方法和分析工具
8.1 輸出GC日誌
    a.輸入控制檯:
    JVM啓動參數加入-XX:PrintGC -XX:PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime
    分別輸出GC的簡要信息、GC的詳細信息、GC的時間信息、GC形成的應用暫停時間

    b.輸入到指定文件
    JVM啓動參數中再加入-Xloggc:gc.log

可用於GC跟蹤分析的參數還有-verbose:gc、-XX:+PrintTenuringDistribution等

8.2 JConsole 
    JDK5自帶工具,位於JDK的bin目錄下,窗口化直接查看JVM信息

    JVisualVM
    JDK6 可查看JVM內存消耗,線程執行,消耗CPU、內存動做,能夠安裝VisualGC插件分析GC

    JMap
    JDK的bin目錄,能夠查看各個代的內存情況、JVM中對象的內存佔用情況

    JHat 
    JDK6中自帶肥西Jvm堆 dump 文件的,分析jvm heap中對象內存佔用情況、以及引用關係。

    JStat
    JDK的bin目錄下,除了分析GC,還能夠用於分析編譯的情況、class加載的情況等

    Eclipse Memory Analyzer
    Eclipse 提供用於分析jvm堆 dump文件的插件,對象內存佔用、引用關係、分析內存泄漏等。
    http://www.eclipse.org/mat/    




相關文章
相關標籤/搜索