中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中雙12壓測引出的線上Full GC怎么排查

發布時間:2021-12-08 09:20:18 來源:億速云 閱讀:163 作者:iii 欄目:云計算

這篇文章主要介紹“java中雙12壓測引出的線上Full GC怎么排查”,在日常操作中,相信很多人在java中雙12壓測引出的線上Full GC怎么排查問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java中雙12壓測引出的線上Full GC怎么排查”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

線上問題

雙12之前壓測的時候起了很小的量,直接觸發了Full GC,嚇尿了,因為馬上雙12大促預熱就要開始了,這搞不好妥妥的3.25啦。

java中雙12壓測引出的線上Full GC怎么排查

趕緊拉群,把相關同學拉在一起排查問題。

java中雙12壓測引出的線上Full GC怎么排查

第一時間查看GC日志:

java中雙12壓測引出的線上Full GC怎么排查

可以看到原因是超過了Metadata GC的閾值,觸發了Full GC,Metaspace從243M 回收到231M,基本沒怎么回收掉,所以稍微再來點量,很容易再次觸發Metaspace 的回收。

 

知識儲備

GC問題排查需要很多儲備知識,最主要是JVM相關的,之前文章已經講過一些了,這里主要講Matespace是什么?后面講怎么做的GC問題的排查。

java中雙12壓測引出的線上Full GC怎么排查

這里有二個知識點:

  • Matespace(元空間)是什么?在JVM中扮演什么角色,也就是存放什么的?
  • Full GC跟Matespace 大小設置有什么關系?

Matespace叫做元空間,從JDK 8開始,永久代(PermGen)的概念被廢棄掉了,取而代之的是一個稱為Metaspace的存儲空間。

Metaspace用來存放:Class文件在JVM 里的運行時數據結構;以及存Klass相關的其他的內容,比如Method,ConstantPool等。

Metaspace使用的是本地內存,而不是堆內存,也就是說在默認情況下Metaspace的大小只與本地內存大小有關。但是很容易有個誤區是Matespace可以隨便用,不管使用多少,只要不超本地內存就不會觸發GC,這是錯誤的。

Matespace的設置方式是:-XX: MetaspaceSize=**M, 這個JVM參數的作用是讓Matespace 達到MetaspaceSize時觸發Full GC, 如果不設置Matespace, 默認值很小,也就 20M左右(不同系統會有一點差別),如果程序Load Class比較多,很容易觸發Full GC。這里要明白的是Class信息和加載Class 的ClassLoader 都存放在Metaspace,我們知道一個類是由這個類的類加載器加上全限定名(由包名&類名組成)確定唯一性的。

所以大家可以檢查一下自己應用JVM Metaspace 設置的大小,如果沒設置可以通過 -XX:+PrintFlagsInitial 查看一下默認值。

(之前文章發過GC日志的詳細講解以及JVM 參數的配置說明,如果有疑問的同學可以去看看歷史文章。)

 

問題排查

剛開始看到 Full GC頻繁,查看日志是由于Metaspace 空間不夠造成的,第一反應是調整Metaspace 大小,把MetaspaceSize 從256M提高到了512M。但是發現Metaspace引發的Full GC還是沒有消除。

java中雙12壓測引出的線上Full GC怎么排查

立即dump了二臺機器的日志,第一次分析GC 日志文件,沒發現異常,這里有個注意的地方,大家dump文件時機很重要,有時候dump 的GC 日志沒問題是因為剛好 Full GC完成之后dump的,內存回收的干干凈凈,有些內存緩慢增加的問題一定要在Full GC前dump。

期間我們還發現緩存相關的對象占用內存較高,但是經過分析,緩存對象生命周期本身就比較長,所以常駐在堆上,沒有問題,繼續看。

排查發現Metaspace內存占用是隨著雙12新接口壓測流量的增長而增長,所以可以確定是新接口代碼引入。

java中雙12壓測引出的線上Full GC怎么排查

分析GC dump日志發現可疑點,同一個ClassCloader 加載了接近3000個,如下圖所示,前面我們說過,ClassCloader 信息在Metaspace 區域。

java中雙12壓測引出的線上Full GC怎么排查破案了,fastjson使用不當引入了ASM Serializer的坑。

 

故障定位&修復

FastJson之所以快,原因就是使用asm字節碼增強替代了反射。所以肯定是代碼中應用了fastjson的ASM處理數據時造成的頻繁加載同一個類,基本問題清楚了,那就是擼代碼了,很快就定位了問題代碼。

因為保密原因,不方便放原始代碼,安琪拉擼了個類似邏輯的代碼:

for(Item item -> arrays) {
  SerializeConfig serializeConfig = new SerializeConfig();
   serializeConfig.put(Custom.class, new CustomSerializer());
   jsonString = JSON.toJSONString(item, serializeConfig);
}
 

這段代碼是自定義了一個序列化實現類CustomSerializer,在進行序列化時進行了一個類似AOP的切面處理,對所有Custom類型的字段進行統一自定義序列化(使用CustomSerializer)。

實現原理上是對需要序列化的Class使用asm動態生成了代理類,在這里就是Item類,使用SerializeConfig配置動態生成字節碼代理類: com.alibaba.fastjson.serializer.ASMSerializer_1_Item,但是每次new SerializeConfig對象,會當作每次代理的目標是不一樣的,導致每次會使用一個新的類加載器ASMClassLoader,所以Metaspace很快就滿了,觸發了頻繁Full GC。

如果希望深入研究可以看下FastJson源碼:

com.alibaba.fastjson.serializer.SerializeConfig#createASMSerializer

問題修復:

注冊ObjectSerializer,讓ObjectSerializer 成為全局唯一的,相當于是單例的。

SerializeConfig.getGlobalInstance().put(Character.class, new CharacterSerializer()); 

SerializeConfig 改成單例的后,每次序列化不用重復加載。

類似問題排查 & 調優

  1. 如果dump 日志發現很多classloader 名稱前綴相同,排查是否有這種動態代理技術的使用,可能在不斷生成代理對象。
  2. 發現內存緩慢增長,GC回收不掉,dump GC日志,查看是否有類被重復加載;
  3. Metaspace調優,比如我們現在生產環境 Metaspace 基本會設置256M 或者512M,可以根據應用的類型和機器內存配置來決定,因素:1. 是否會加載比較多的類,2. 機器內存允許, 可以適當調大Metaspace。

到此,關于“java中雙12壓測引出的線上Full GC怎么排查”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

稻城县| 安徽省| 澄迈县| 林周县| 宝鸡市| 盐源县| 土默特左旗| 甘泉县| 永福县| 元氏县| 永州市| 恭城| 台北县| 许昌市| 淳安县| 荔浦县| 景宁| 化德县| 中山市| 汉中市| 尉犁县| 寿阳县| 聊城市| 义马市| 崇义县| 南陵县| 肥西县| 将乐县| 台安县| 永和县| 镇雄县| 汝阳县| 东乌珠穆沁旗| 九江市| 唐海县| 礼泉县| 荣成市| 澄城县| 崇义县| 富民县| 舟山市|