- 本章介紹GC原理 , 幫助調教JVM效能
- FLOW
- 引用計數法 (Reference Counting)
- 標記清除法(Mark-Sweep)
- 複製算法 (Copying)
- 標記壓縮法 (Mark-Compact)
- 分代算法 (Generational Collecting)
- 分區算法 (Region )
- Detail
- 1a 檢查物件是否引用 , 缺點是兩物件互相引用造成垃圾無法識別
- 2a 在記憶體中,從各根節點開始出發 , 在路徑上找出未被引用的對象並清除 , 缺點是容易造成記憶體空間碎片 , 如果空間不連續工作效率較差
- 3a 將內存空間非為兩塊 , 每次只使用一塊 , GC時將存活對象複製到另一塊 , 因此沒有碎片 , 缺點是內存必須折半和存活對象不斷複製
- 4a 執行標記清除法(Mark-Sweep)後 , 重整存活之記憶體
- 5a 基於各內存空間的特性 , 採用不同的演算法
- java GC 時 , 新生代空間採用複製算法(copying) , 老年代採用標記壓縮法(Mark-Compact)或標記清除法(Mark-Sweep)
- 為了加速高GC頻率的新生代 , java使用Card Table紀錄是否被老年代引用 , 也不用掃描全部老年代空間
- 6a 將內存區域區合理切成多個小塊空間 , 控制每次GC多少個小區間 , 可減少GC所產生的停頓時間
- 本章敘述JVM常用參數 參考網址
- Flow
- 追蹤垃圾回收機制的追蹤
- class加載/卸載的追蹤
- 系統參數的追蹤
- 設置Heap
- 設置新生代 ( Young generation )
- OOM處理
- Method area與stack配置如第一章
- 配置直接內存
- 虛擬機的工作模式( client/server)
- Detail
- 1a 常用參數
- # -XX:+PrintGC 輸出GC日誌
- # -XX:+PrintGCDetails 輸出GC的詳細日誌 , 另外JVM結束後打印出更多Heap信息
- # -XX:+PrintGCTimeStamps 輸出GC的時間戳(JVM啟動後的秒數位置)
- # -XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800
- # -XX:+PrintHeapAtGC 每次在進行GC的前後打印出更多heap的信息
- # -Xloggc:../logs/gc.log 日誌文件的輸出路徑
- #-XX:+PrintGCApplicationConcurrentTime 輸出執行GC , application當前時間戳
- #-XX:+PrintGCApplicationStoppedTime 輸出執行GC , application thread暫停時間
- 1b 主要描述內容
- [GC 使用量(前) ->使用量(後)(當前可用空間)]
- 2a 常用參數
- # -XX:+TraceClassLoadding 加載時
- # -XX:+TraceClassUnLoadding 卸載時
- # -XX:+PrintClassHistogram 開發工具console使用 (Ctrl+break)
- 3a 常用參數
- # -XX:+PrintVMOptions 打印顯示參數
- # -XX:+PrintCommandFlags 打印顯示和隱示(JVM自設)參數
- # -XX:+PrintFlagsFinal 打印完整參數
- 4a 常用參數
- # -Xms 初始大小 ,JVM會盡可能維持在這大小內運行
- # -Xmx 最大空間 , JVM會拉一些空間給GC使用
- 4b 當Heap free空間不足時 , 會促使total空間向上擴展 , 但不超過max空間限制
- 4c 建議可直接將 -Xms 與 -Xmx 設置相等 , 可減少GC次數 , 提高效能
- 5a 常用參數
- # -Xmn 新生代空間 , 建議為Heap空間的 1/3~1/4左右
- # -XX:SurvivorRatio Eden空間 與 From/To空間比例
- # -XX:NewRatio 老年代空間 與 新生代空間比例
- 5b 新生代可用空間 = Eden+(From/To)
- 5c 當創建實例 , Eden區上和其中一塊倖存區仍標記存活的對象複製到另一塊倖存區, 當一塊倖存區空間不足或存活時間夠久時 , 則存放到老年代
- 5d 建議將對象存在新生代中 ,減少額外對老年代GC的次數
- 6a 常用參數
- # -XX:+HeapDumpOnOutOfMemoryError OOM發生時打印Heap訊息
- # -XX:+HeapDumpPath OOM發生時產生文件
- # -XX:+OnOutOfMemoryError OOM發生時執行腳本
- 8a 常用參數
- # -XX:MaxDirectMemorySize 預設同-Xmx
- 8b -server參數可幫助優化
- 8c 直接內存適合內存空間(new)申請次數少的場合 , 否則效能會比操作heap內存低
- 9a server模式啟動速度慢但效能高 , client模式反之
- 本章講述 JVM基本結構和物件產生流程
- Flow 參考網址
- 類裝載器加載Class訊息存放於Method Area
- 每一條thread 創建 java Stack 、PC寄存器
- 創建實例(new)存放於Heap
- 局部變量、參照存放於Java Stack
- 垃圾回收系統處理範圍包含直接內存、Method Area、Heap
- Detail
- *1 Method Area
- 共享空間
- 存放class訊息、常量池( <= jdk1.6)
- 指令
- # -XX:PermSize=5M 初始值 (默認64M)
- # -XX:MaxPermSize=5M 上限值
- 在 JDK 1.8已由Metadata area取代(使用直接內存 , 無預設大小)
- *2 PC寄存器
- 私有空間
- thread總是在執行方法 , PC寄存器會指向正在執行的指令或undefined(本地方法)
- *3 Heap
- 共享空間
- 包含常量池( >= jdk1.7)
- 包含新生代 [ eden 、 s0(from)、s1(to) ]
- 包含老年代 [tenured]
- 每一次回收後 , 保留資料年齡+1
- 例外
- java.lang.OutOfMemoryError
- 指令
- 可將處理對象原本存放在Heap的資料 , 改存在 Stack上 , 好處是當函數結束後自動銷毀 , 不須等待回收機制
- 適用在小而多的對象
- 處理對象不可被任何 thread 訪問 , 例入區域變數或者無返回值
- # -server XX:+DoEscapeAnalysis 啟用分析
- # -XX:+EliminateAllocations 打散在Stack上
- *4 Java Stack
- 私有空間
- 先進後出
- Native Method Stack用於調用local端lib的方法
- 每當函數執行時創建一個Stack frame , 存放局部變量表、中間運算結果 , 函數執行完畢移除
- 例外
- StackOverflowError Exception
- 指令
- 局部變量表的存放空間可重用 , 善用 { } 製造區域變數 , 減少存放空間
- *5 垃圾回收機制
- 指令 System.gc();
- 回收能否成功 , 須看是否有參照=
- 當變量參照=null 或 {}包含 , 方可回收
- 指令