1. Jvm調優
1.1. 最佳實踐
@最大堆內存和最小堆內存設置一樣大
@設置線程棧大小爲512或者甚至256,一般情況下,默認1Mb太大了
@設置大對象大小閘閥,大對象直接在年老代分配,否則可能會頻繁造成ygc
@-XX:+UseAdaptiveSizePolicy 該參數開啓,讓ps垃圾回收器調整最優策略
1.2. 問題定位工具
1.2.1. Jvisual(jconsole升級版)
在jdk的bin目錄下能找到。通過工具還可以添加插件。其中包括gc的一個插件,可以查堆各個模塊的內存情況,及其動態的回收情況。查看線程情況。
之前就遇到過一個情況,一個同事,在寫一個回調方法中,用了線程池,線程池不是靜態化的,導致觸發一次就會創建一個線程池,導致創建大量線程,我就是通過jvisual輕鬆拿下的。
1.2.2. Jstack
jstack可以定位到線程堆棧,根據堆棧信息我們可以定位到具體代碼。
第一步,得到服務進程的pid
第二步,top -Hp pid,查詢最消耗內存的線程 --》21742
第三步,printf "%x\n" 21742,得到一個16進制的數,假定爲54ee
第四步,jstack 21711 | grep 54ee,可以定位到具體的類的方法
1.2.3. Gc日誌
開啓gc日誌,
通過https://gceasy.io/分析gc日誌,得到分析詳細的垃圾回收信息,非常詳細
1.2.4. 垃圾回收器選擇
不同場景運營不用垃圾回收器
Serial,串行,單cpu 下性能極好
Ps垃圾回收器,1.8jdk默認,可以設置最大停頓時間和吞吐量
G1(garbege first)1.9默認,在垃圾回收器中是最前沿的技術之一
1.2.5. 高版本JDK下的gc
ZGC(jdk11)
低延遲的ZGC,不管堆內存多大,都能使得STW時間不會超過10ms;和現有的G1相比,應用吞吐能力的下降不會超過15%
ZGC是一個併發、基於區域(region)、標記壓縮算法的GC,只有根結點掃描階段會發生STW,因此停頓時間不會隨着堆內存的增長和存活對象的增長而增長
目前ZGC只能用於64位的linux操作系統下
Shenandoah(雪蘭多)
最大的區別在於雪蘭多收集器實現了併發疏散環節,引入的Brooks Forwarding Pointer技術使得GC在移動對象時,對象的引用仍然可以訪問,這樣就降低了延遲,相關團隊宣城是使99.9%的暫停小於10ms。
G1可終止的混合垃圾回收(jdk12),主要思路是:把回收集分爲必須部分和可選部分,優先處理必須部分。
1.2.6. 其他
Jmap,jstat,其實在gceasy,和jvisual都包含了類似的功能。
參考 https://blog.csdn.net/qq_37475168/article/details/107108462 不通版本jdk
https://my.oschina.net/feichexia/blog/196575 jvm調優實戰