最近一直被內存溢出捆擾,現在對這幾天的工作做個小小的總結!另外給首次與到此類問題的小鳥們作個提示,希望大家早日變成老鳥!
1 首先確認是不是內存溢出,如果直接報OutOfMemoryException,那肯定是內存溢出,有時可能沒有發現這個錯誤,但WEB服務到最后還是掛了,也有可能是由Memory Out,如何確認,最好的辦法就是查看gc日志。
2 如果確認是內存溢出,不要急著跟蹤,因為要找到確切位置還是有一定困難的,個人建議對最近修改的代碼作一次全面檢查,對于有可能出現內存溢出的地方作些修改。
可能出現的原因:
(1) 遞歸、循環,這里要注意隱性的地筆,如攔載器,我自已遇到一次攔載器的死循環
(2) static 的對象,查看static里面是不是有大量的對象塞進去
(3)Set/List/Map對象,查看Set/List/Map里面是不是有對象用完了沒有釋放
(4)session/application,查看session里的對象、過期時間等,看是不是無法即時釋放
(5)ClassLoader,Java ClassLoader結構的使用為內存泄漏提供了許多可乘之機。這個我不知道深層原因,有知道的可以告訴我,將不勝感謝!
(6)String,字符串累加也容易出現溢出。一般順序StringBuilder,StringBuffer,String。
(7)全局變量,盡量不使用,使用了即時釋放
修改后再查看日志,也許問題已經解決了。
3 如果還是有溢出就只能上工具了,我使用的是JProfiler,功能很強大,首先我在window上遠程監控linux,結果失敗,原因是因為JProfiler本身就有很大的消耗,而且在測試中還要不斷gc,影響生產,所以選用在測試環境中配合jmeter測試。
4 測試方法:循環測試,查看gc后是否有對象數量不斷增加,即有對象未釋放。
5 其此是要了解java內存分配原理和gc的工作原理,這樣才可以定位到問題的具體位置。
6 對jvm進行優化。
具體操作未詳細說明,可以參考相關資料
java內存泄漏原因 http://www.ibm.com/developerworks/cn/java/l-JavaMemoryLeak/
gc原理http://chenchendefeng.javaeye.com/blog/455883
jvm優化http://www.cjsdn.net/post/view?bid=1&id=197954
JVM調優-解決native heap持續增長 http://sw1982.javaeye.com/blog/724626 薦