5.1 調優領域
- 內存
- 鎖競爭
- cpu佔用
- io
5.2 確定目標(垃圾回收階段)
- 【低延遲】還是【高吞吐量】,選擇合適的回收器
* 互聯網項目追求的是低延遲 - CMS,G1,ZGC:響應時間優先的垃圾回收器
- ParallelGC:高吞吐量垃圾回收器
- Zing
5.3 最快的GC是不發生GC
5.4 新生代調優
- TLAB (Thread Local Allocation Buffer,線程本地分配緩衝區)是 Java 中內存分配的一個概念,它是在 Java 堆中劃分出來的針對每個線程的內存區域,專門在該區域爲該線程創建的對象分配內存。它的主要目的是在多線程併發環境下需要進行內存分配的時候,減少線程之間對於內存分配區域的競爭,加速內存分配的速度。
5.4.1新生代調優方法
- 新生代內存越大越好?
- 設置小,不太好,可用空間小,空間不足時,會執行mirro GC,會有短暫的STW
- 設置大了,老年代的可用空間小,老年代存的少,會執行Full GC,STW時間更長
Oracle中的建議新生代比例1/4-1/2之間
理想情況:
- 新生代能容納【併發量*(請求-響應)】的數據
- 倖存區達到能保留【當前活躍對象+需要晉升對象】
* 當前活躍對象:生命週期較短,下次有可能被回收
* 需要晉升對象:將來肯定晉升的老年代
如果過小的話,本來會繼續存儲在倖存區中,此時會被晉升至老年代,增加老年代垃圾回收時間
如果不晉升至老年代,會在新生代的倖存區進行來回複製,會降低性能。因爲:新生代複製算法,主要的耗時在於複製上
5.5 老生代調優
一般75%-80%:浮動垃圾佔比20-25%
5.6 案例
-
案例1:Full GC和MinorGC頻繁
-
原因分析:空間緊張,如果當新生代內存較小,業務繁多,會將新生代塞滿。倖存區空間緊張,導致晉升的閾值減少
導致本來不改晉升的對象,晉升至老年代,老年代中存放着生命週期短的對象,會加速老年代內存塞滿,導致老年代的FullGC頻繁- 解決方法:內存優化先從新生代開始,先增大新生代內存,同時增大的S區的內存,和晉升的閾值。
-
案例2:請求高峯期發生FullGC,單次暫停時間特別長(CMS)
原因分析:CMS中,初始標記和併發標記的時間都是很快,而重新標記的時間會很難,因爲重新標記時,會掃描整個內存,新生代和老年代都會掃描。如果業務多,老年代會引用新生代,遍歷算法會耗時很多。
解決方法:在重新標記之前,對新生代進行垃圾回收,設置參數CMSScavengeBeforeRemark。
-
-
案例3:老年代充裕情況下,發生Full GC(CMS jak1.7)