JVM中垃圾回收調優

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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章