使用反射代理类加载器的潜在内存使用问题
問題(摘要)
大量的類加載器 sun/reflect/DelegatingClassLoader,用來加載sun/reflect/GeneratedMethodAccessor類,可能導致潛在的占用大量本機內存空間問題。
癥狀
應用服務器進程占用的內存會顯著增大。您還有可能遇到拋出的內存溢出錯誤。
原因
當使用Java反射時,Java虛擬機有兩種方法獲取被反射的類的信息。它可以使用一個JNI存取器。如果使用Java字節碼存取器,則需要擁有它自己的Java類和類加載器(sun/reflect/GeneratedMethodAccessor類和sun/reflect/DelegatingClassLoader)。這些類和類加載器使用本機內存。字節碼存取器也可以被JIT編譯,這樣會增加本機內存的使用。如果Java反射被頻繁使用,會顯著地增加本機內存的使用。
Java虛擬機會首先使用JNI存取器,然后在訪問了同一個類若干次后,會改為使用Java字節碼存取器。這種當Java虛擬機從JNI存取器改為字節碼存取器的行為被稱為膨脹。幸運的是,我們可以通過一個Java屬性控制這種行為。屬性sun.reflect.inflationThreshold會告訴Java虛擬機使用JNI存取器多少次。如果設為0,則總是使用JNI存取器。由于字節碼存取器比JNI存取器使用更多本機內存,當我們看到大量Java反射時,最好使用JNI存取器。我們只需要設置inflationThreshold屬性值為0即可。
診斷問題
如果在javacore或heapdump中有大量sun/reflect/DelegatingClassLoader類加載器,您可能遇到了此問題。
解決問題
設置Java屬性sun.reflect.inflationThreshold值為0。
1. 訪問WebSphere應用程序服務器管理控制臺
服務器 > 應用程序服務器 > 服務器名稱
2. 在服務器基礎結構部分,展開Java和進程管理,選擇進程定義
3. 在其他屬性部分選擇Java虛擬機,在通用JVM參數輸入框里添加以下字符串
-Dsun.reflect.inflationThreshold=0
4. 點擊“確定”,保存至主配置。
需要重啟應用程序服務器使設置生效。
相關信息
1566549
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的使用反射代理类加载器的潜在内存使用问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: drools规则引擎因为内存泄露导致的内
- 下一篇: 大量DelegatingClassLoa