欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JVM Metaspace內存溢出問題解決方案

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

一. 現(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ù)據信息,我們的應用里加載的各種類描述信息,比如類名、屬性、方法、訪問限制等,按照一定的結構存儲在Metaspace里。

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

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


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


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


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


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


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



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


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


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

而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就是這樣產生的。

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


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

三. 總結

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

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


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

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

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

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

相關文章

  • 淺談Java中ArrayList的擴容機制

    淺談Java中ArrayList的擴容機制

    本文主要介紹了淺談Java中ArrayList的擴容機制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • java實現(xiàn)服務器文件打包zip并下載的示例(邊打包邊下載)

    java實現(xiàn)服務器文件打包zip并下載的示例(邊打包邊下載)

    這篇文章主要介紹了java實現(xiàn)服務器文件打包zip并下載的示例,使用該方法,可以即時打包文件,一邊打包一邊傳輸,不使用任何的緩存,讓用戶零等待,需要的朋友可以參考下
    2014-04-04
  • java中object類實例分析

    java中object類實例分析

    這篇文章主要介紹了java中object類實例分析,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • Mybatis+Druid+MybatisPlus多數(shù)據源配置方法

    Mybatis+Druid+MybatisPlus多數(shù)據源配置方法

    在項目開發(fā)中,經常需要連接多個數(shù)據庫,使用Mybatis、Druid和MybatisPlus可以實現(xiàn)多數(shù)據源配置,通過定義配置類和修改配置文件,如properties或yaml,可以設置多個數(shù)據源,本文介紹了配置項包括Druid基本配置、數(shù)據源一、數(shù)據源二,感興趣的朋友一起看看吧
    2024-09-09
  • Java編寫緩存工具類的示例代碼

    Java編寫緩存工具類的示例代碼

    這篇文章主要為大家詳細介紹了如何基于Java編寫一個緩存工具類,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的小伙伴可以了解一下
    2023-07-07
  • 一文帶你厲害Java設計模式中的模板方法

    一文帶你厲害Java設計模式中的模板方法

    模板方法定義了一個算法的步驟,并允許子類為一個或多個步驟提供實現(xiàn)。這篇文章就來帶大家了解一下Java模板方法的概念與實現(xiàn),感興趣的小伙伴可以跟隨小編一起學習一下
    2023-01-01
  • Java簡單實現(xiàn)對一串數(shù)字采用相應的加密策略后傳輸

    Java簡單實現(xiàn)對一串數(shù)字采用相應的加密策略后傳輸

    下面小編就為大家?guī)硪黄狫ava簡單實現(xiàn)對一串數(shù)字采用相應的加密策略后傳輸。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • mybatis?實現(xiàn)字段大小寫賦值

    mybatis?實現(xiàn)字段大小寫賦值

    這篇文章主要介紹了mybatis?實現(xiàn)字段大小寫賦值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java編程中的性能優(yōu)化如何實現(xiàn)

    Java編程中的性能優(yōu)化如何實現(xiàn)

    這篇文章主要介紹了Java編程中的性能優(yōu)化如何實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • 解決SpringBoot項目中l(wèi)og4j與logback的Jar包沖突問題

    解決SpringBoot項目中l(wèi)og4j與logback的Jar包沖突問題

    這篇文章主要給大家介紹了解決SpringBoot項目中l(wèi)og4j與logback的Jar包沖突問題,文中有詳細的解決方法和沖突的原因,有遇到相同問題的朋友可以參考閱讀本文
    2023-10-10

最新評論