最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JVM Metaspace內(nèi)存溢出問題解決方案

 更新時間:2020年11月16日 09:27:38   作者:Java老K  
這篇文章主要介紹了JVM Metaspace內(nèi)存溢出排查總結過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

一. 現(xiàn)象

前段時間公司線上環(huán)境的一個Java應用因為OOM的異常報警,導致整個服務不可用被拉出集群,本地模擬重現(xiàn)的現(xiàn)象如下:


當時的解決方案是增加metaspace的容量:-XX:MaxMetaspaceSize=500m,從原來默認的256m改為500m,雖然沒有再出現(xiàn)oom,但這個只是臨時解決方案,通過公司的監(jiān)控系統(tǒng)觀察metaspace的使用情況還是在上升,而且后面隨著業(yè)務訪問量越來越大還是有可能達到閾值。

二. 分析

Metaspace元空間主要是存儲類的元數(shù)據(jù)信息,我們的應用里加載的各種類描述信息,比如類名、屬性、方法、訪問限制等,按照一定的結構存儲在Metaspace里。

由此可知metaspace空間增長是由于反射類加載,動態(tài)代理生成的類加載等導致的,也就是說Metaspace的大小和加載類的數(shù)據(jù)有關系,加載的類越多metaspace占用的內(nèi)存也就越大。

因為了解當時的業(yè)務場景是因為有個郵件服務訪問訂單詳情接口的訪問量突然上升,以及查看log的eroor日志發(fā)現(xiàn)大部分都是訂單詳情接口先報出的這個問題:java.lang.OutOfMemoryError: Metaspace


這里我在測試環(huán)境Java應用的jvm里增加-XX:+TraceClassLoading -XX:+TraceClassUnloading記錄下類的加載和卸載情況,然后通過jmeter多個線程調(diào)用訂單詳情接口模擬metaspace溢出的現(xiàn)象,發(fā)現(xiàn)在catalina.out文件里輸出的除了業(yè)務上用到的類外還有大量的反射類,如下:


這些反射類被頻繁的加載和卸載是不正常的,通過Arthas診斷工具觀察調(diào)用鏈發(fā)現(xiàn)每次調(diào)用接口都是通過反射的方式實現(xiàn)的。


目前我們的項目都是基于SOA框架對外提供訪問的,從上圖sun.reflect的調(diào)用者也能看出來


通過上圖可以看出在調(diào)用底層接口時都是通過反射的方式獲取類的實例,查看框架底層代碼實現(xiàn)可以確認


同樣對底層接口返回的json數(shù)據(jù)反序列化時也會用到反射



繼續(xù)跟代碼可以看到這些反射的實現(xiàn)都會用到java.lang.Class里的ReflectionData對象


ReflectionData是個內(nèi)部靜態(tài)類被緩存起來,里面的屬性就是我們做反射操作時需要用的屬性Field,方法Method和構造函數(shù)等。但是有個問題reflectionData是被SoftReference軟引用修飾的,如下圖


如果是軟引用的話在內(nèi)存空間不足時就可能會被回收掉,如果回收掉那下次再使用的話只能重新通過反射獲取。

而SoftReference是否被回收又跟SoftRefLRUPolicyMSPerMB參數(shù)的值有關系,查看我們線上JVM的配置發(fā)現(xiàn)XX:SoftRefLRUPolicyMSPerMB這個參數(shù)設置的是0


SoftRefLRUPolicyMSPerMB這個參數(shù)大概意思是每1M空閑空間可保持的SoftReference對象的生存時長(單位是ms毫秒),LRU是Least Recently Used的縮寫,最近最少使用的。

這個值jvm默認是1000ms,如果被設置為0,就會導致軟引用對象馬上被回收掉,進而會導致重新頻繁的生成新的類,而無法達到復用的效果。

上圖里大量的sun.reflect.GeneratedSerializationConstructorAccessor,GeneratedMethodAccessor就是這樣產(chǎn)生的。

我把這個參數(shù)改回默認值-XX:SoftRefLRUPolicyMSPerMB=1000 (1秒),發(fā)布到生產(chǎn)環(huán)境驗證了下,發(fā)布后就降下來了,到今天為止基本上趨于穩(wěn)定


調(diào)整后基本上沒有再出現(xiàn)波動

三. 總結

  • 目前主要是通過修改JVM的-XX:SoftRefLRUPolicyMSPerMB值來解決metaspace上升問題,后續(xù)會持續(xù)觀察變化,適當調(diào)整參數(shù)。至于這個參數(shù)之前為什么會被設置成0, 還需要找ops確認下。
  • 我們的應用需要大量RPC交互,屬于I/O密集型業(yè)務,使用SOA,Dubbo都會遇到類似的問題,通過上面的源碼分析可以看出這個是無法避免的(除非是換一種序列化協(xié)議,比如hessian,不走方法反射的方式來賦值)包括本身使用的Spring框架很多地方也是通過反射實現(xiàn)的比如AOP,還有我們埋點經(jīng)常使用的JsonUtils工具,通過dump文件也能看出來存在大量的屬性拷貝和反射操作。

所以我們在平時的業(yè)務代碼開發(fā)中如果遇到兩個對象賦值的操作盡量少用反射的方式實現(xiàn),比如下面的代碼:


這里做的對象拷貝操作使用的是apache common-beanutils.jar中的BeanUtils,這個類底層采用javabeans+反射實現(xiàn),性能比較差,內(nèi)存開銷比較大,當系統(tǒng)高并發(fā)的情況容易導致Metaspace空間增長過快,不建議這樣使用。

如果字段少的話直接賦值就行了,多的話可以使用Cglib的BeanCopier類,BeanCopier類底層是采用asm字節(jié)碼操作方式來進行對象拷貝操作,性能損耗和內(nèi)存開銷都比較小。

或者使用MapStruct這種幫你生成set、get方法的工具,效果會更好。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Java中使用JWT生成Token進行接口鑒權實現(xiàn)方法

    Java中使用JWT生成Token進行接口鑒權實現(xiàn)方法

    這篇文章主要介紹了Java中使用JWT生成Token進行接口鑒權實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • java中charAt()方法的使用及說明

    java中charAt()方法的使用及說明

    這篇文章主要介紹了java中charAt()方法的使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 學習Java之如何正確地跳出循環(huán)結構

    學習Java之如何正確地跳出循環(huán)結構

    我們在利用循環(huán)執(zhí)行重復操作的過程中,存在著一個需求:如何中止,或者說提前結束一個循環(huán),所以就給大家講解一下,如何在java代碼中返回一個結果,如何結束和跳出一個循環(huán),需要的朋友可以參考下
    2023-05-05
  • Java語言中flush()函數(shù)作用及使用方法詳解

    Java語言中flush()函數(shù)作用及使用方法詳解

    這篇文章主要介紹了Java語言中flush函數(shù)作用及使用方法詳解,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Java實現(xiàn)從jar包中讀取指定文件的方法

    Java實現(xiàn)從jar包中讀取指定文件的方法

    這篇文章主要介紹了Java實現(xiàn)從jar包中讀取指定文件的方法,涉及java針對jar文件的讀取及查找相關操作技巧,需要的朋友可以參考下
    2017-08-08
  • Java方法上注解值修改不成功的問題

    Java方法上注解值修改不成功的問題

    這篇文章主要介紹了Java方法上注解值修改不成功的解決方法,本文結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • 劍指Offer之Java算法習題精講數(shù)組與二叉樹

    劍指Offer之Java算法習題精講數(shù)組與二叉樹

    跟著思路走,之后從簡單題入手,反復去看,做過之后可能會忘記,之后再做一次,記不住就反復做,反復尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質(zhì)的變化
    2022-03-03
  • 深入了解Java排序算法

    深入了解Java排序算法

    本文主要介紹了深入了解Java排序算法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2007-03-03
  • Java中controller層如何接收帶參數(shù)的查詢

    Java中controller層如何接收帶參數(shù)的查詢

    本文主要介紹了Java中controller層如何接收帶參數(shù)的查詢,在控制器層接收帶參數(shù)的查詢可以通過多種方式實現(xiàn),下面就詳細的介紹一下,感興趣的可以了解一下
    2023-08-08
  • Java Junit單元測試實例詳解

    Java Junit單元測試實例詳解

    在本篇文章里小編給大家分享的是關于Java Junit單元測試的相關知識點內(nèi)容,有興趣的朋友們學習下。
    2019-11-11

最新評論

法库县| 郴州市| 桐庐县| 古浪县| 车险| 盐山县| 易门县| 云南省| 麟游县| 宜阳县| 车险| 双峰县| 连江县| 台山市| 科尔| 四子王旗| 马龙县| 咸阳市| 黄龙县| 颍上县| 庐江县| 长岛县| 沭阳县| 左权县| 大兴区| 喀喇| 沧州市| 昌都县| 额尔古纳市| 当雄县| 福海县| 通江县| 普安县| 景谷| 灵宝市| 牡丹江市| 武乡县| 惠水县| 诏安县| 石狮市| 方山县|