java反射造成的內存泄露解決方法

   做了一個項目, 到現場運行時老有內存泄露問題, 怎麼改都解決不了問題. 在測了n多次之後, 終於發現了這麼一個錯誤提示, 項目用的操作系統是IBM的axis:

Exception in thread "Attach API wait loop" java.lang.reflect.InvocationTargetExceptionjava.lang.OutOfMemoryErrorjava.lang.reflect.InvocationTargetException


        at com.ibm.tools.attach.javaSE.AttachHandler.terminate( at sun.reflect.GeneratedMethodAccessor29.invoke(Unknown Source)AttachHandler.java
:       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)4
2       at java.lang.reflect.Method.invoke(Method.java:611)2
)       at com.web.utils.Utils.reflectExeMethod(Utils.java:156)
        at sun.reflect.GeneratedMethodAccessor30.invoke(Unknown Source)...

  google一下,沒找到類似的錯誤信息,不過看着也知道是反射引起的問題. 再幾番測試後,最終確定, 是項目用了極其大量的反射而造成了內存泄露. 這一般會報如下異常(俺的這個項目沒有報該異常, 這應該與ibm的操作系統有關):

 

異常: java.lang.OutOfMemoryError: PermGen space

說明:

    Perm空間被佔滿。無法爲新的class分配存儲空間而引發的異常。這個異常以前是沒有的,但是在Java反射大量使用的今天這個異常比較常見了。主要原因就是大量動態反射生成的類不斷被加載,最終導致Perm區被佔滿。

    更可怕的是,不同的classLoader即便使用了相同的類,但是都會對其進行加載,相當於同一個東西,如果有N個classLoader那麼他將會被加載N次。因此,某些情況下,這個問題基本視爲無解。當然,存在大量classLoader和大量反射類的情況其實也不多。

解決:

    1. -XX:MaxPermSize=16m

    2. 換用JDK。比如JRocket

最後,我在啓動文件"***.sh"中添加了-XX:MaxPermSize=4096m,終於解決了問題, "***.sh"如下:

chmod u+x ***.jar
nohup java -jar -Xms1024m -Xmx4096m -XX:MaxPermSize=4096m ***.jar &

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章