1. 元空間(metaspace) 1.1. 當JVM載入類時,它必須記錄這些類的某些元數據,這些數據占據的一個單獨的堆空間,即元空間 1.2. 元空間里的信息只在編譯器和JVM運行時使用,它所保存的數據被稱為類元數據(class metadata) 1.2.1. 對於終端用戶,元空間是不透明的 1 ...
1. 元空間(metaspace)
1.1. 當JVM載入類時,它必須記錄這些類的某些元數據,這些數據占據的一個單獨的堆空間,即元空間
1.2. 元空間里的信息只在編譯器和JVM運行時使用,它所保存的數據被稱為類元數據(class metadata)
1.2.1. 對於終端用戶,元空間是不透明的
1.2.2. 元空間並不保存類的實例或者反射對象
1.3. 通過永久代(permgen)的實現來處理的
1.4. 元空間的大小與它所使用的類的數量成正比
1.5. -XX:MetaspaceSize=N
1.5.1. 初始大小
1.6. -XX:MaxMetaspaceSize=N
1.6.1. 最大值
1.7. 元空間大小的預設值
1.7.2. 優化永久代在過去相當普遍,而現在優化元空間相當罕見,因為空間豐富
1.8. 調整元空間的大小會導致Full GC,這是代價高昂的操作
1.9. 如果在應用程式的啟動過程中(它在載入類)有大量的Full GC,往往是因為永久代或元空間正在調整大小
1.10. 定義並丟棄大量類的應用程式,在元空間被填滿且舊的類被刪除時,偶爾會發生Full GC。這在開發環境中很常見
1.11. 伺服器通常將元空間的初始大小設定為128 MB、192 MB或更大
1.12. 增加元空間的初始值是改善啟動過程的好主意
1.13. 元空間的初始大小可以基於所有類都載入之後的使用量來設置,這會稍微加快啟動速度
1.14. 限制元空間大小的一個原因是防止類載入器泄漏
1.15. jmap可以和-clstats一起使用,以輸出有關類載入器的信息
2. 控制並行
2.1. 除了Serial垃圾回收器,所有的GC演算法都使用了多線程
2.2. -XX:ParallelGCThreads=N
2.2.1. 設置線程的數量
2.2.2. 使用-XX:+UseParallelGC時新生代的回收
2.2.3. 使用-XX:+UseParallelGC時老年代的回收
2.2.4. 使用-XX:+UseG1GC時新生代的回收
2.2.5. G1 GC的STW停頓階段(不包括Full GC)
2.3. 預設情況下,JVM將在機器的每個CPU上都運行一個線程,最多同時運行8個,達到這個閾值後,JVM每1.6個CPU會再增加一個新線程
2.4. 超過8個CPU的機器上,線程總數計算
2.4.1. ParallelGCThreads = 8 + ((N - 8) * 5 / 8)
2.4.2. N表示CPU的數量
2.5. 如果機器上運行的JVM不止一個,那麼最好限制所有JVM的GC線程總數
2.6. 當多個JVM運行在同一臺機器上時,基於公式計算出的線程數量會過高,實際情況中必須減少使用的線程數量
3. GC工具
3.1. GC日誌是診斷GC問題所需的關鍵數據,應該定期收集它們(即使是在生產伺服器上)
3.2. 在JDK 8中開啟GC日誌
3.2.1. 設定-verbose:gc和-XX:+PrintGC中的任意一個,都會創建簡單的GC 日誌
3.2.1.1. 這兩個標誌是彼此的別名
3.2.1.2. 日誌預設情況下是關閉的
3.2.2. -XX:+PrintGCDetails
3.2.2.1. 推薦使用
3.2.2.2. 將創建包含更多信息的詳細日誌
3.2.2.3. 預設情況下是false
3.2.3. -XX:+PrintGCTimeStamps
3.2.3.1. 確定GC操作之間的時間
3.2.3.2. 時間戳(time stamp)是相對於0的(基於JVM啟動的時間)值
3.2.4. -XX:+PrintGCDateStamps
3.2.4.1. 確定GC操作之間的時間
3.2.4.2. 日期戳(date stamp)是實際的日期字元串
3.2.4.3. 日期戳需要格式化,這使得日期戳的效率略低
3.2.5. -Xloggc:filename
3.2.5.1. 預設被寫入標準輸出
3.2.5.2. 改變被寫入的位置
3.2.5.3. 可以自動開啟簡單GC日誌
3.2.6. 日誌文件的滾動
3.2.6.1. 可以限制GC日誌中保存的數據量
3.2.6.2. -XX:+UseGCLogFileRotation
3.2.6.2.1. 預設關閉的
3.2.6.2.2. 開啟時
3.2.6.2.2.1. -XX:NumberOfGCLogFiles=N
3.2.6.2.2.2. 預設的文件數量是0(意味著無限多)
3.2.6.2.2.3. -XX:GCLogFileSize=N
3.2.6.2.2.4. 預設的日誌文件大小是0(意味著無限大)
3.2.6.3. 示例
3.2.6.3.1. ***-Xloggc:gc.log -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFile=8 -XX:GCLogFileSize=8m***