內(nèi)存問題錯(cuò)綜復(fù)雜,本人水平也有限,淺薄之見僅供參考。
一、GC監(jiān)控
GC日志記錄了內(nèi)存使用和回收狀態(tài),出現(xiàn)內(nèi)存故障時(shí),可作為分析排查手段。
1. 啟用GC監(jiān)控的方法:增加java啟動(dòng)參數(shù)-verbose:gc,輸出信息的樣例:










2. 將GC日志輸出到文件:不同JDK設(shè)置的參數(shù)不同,參考JDK官方文檔
?? SUN:-Xloggc:filename (例如:-Xloggc:D:/gc.log)
?? IBM:-Xverbosegc:file=filename 或 -Xverbosegclog:filename
?? HP?:-Xverbosegc=filename??
3. 如何設(shè)置Java啟動(dòng)參數(shù):有多種方式,以下各舉一例
?? Tomcat:在catalina.bat的“set JAVA_OPTS=%JAVA_OPTS% ”后設(shè)置
?? WebLogic:在startWebLogic.cmd的“%JAVA_HOME%\bin\java %JAVA_VM% %MEM_ARGS% %JAVA_OPTIONS% ”后設(shè)置
?? WebSphere:進(jìn)入管理控制臺(tái),應(yīng)用服務(wù)器->進(jìn)程定義->Java虛擬機(jī)高級(jí)定義
4. GC日志的圖形分析工具:HP的jtune
二、內(nèi)存問題描述
典型現(xiàn)象是系統(tǒng)運(yùn)行一段時(shí)間后,報(bào)OutOfMemoryError錯(cuò)誤、頁面非常慢、不響應(yīng)或完全不再接受請(qǐng)求,而此時(shí)通過觀察JVM內(nèi)存,發(fā)現(xiàn)內(nèi)存急劇上升到最大值并居高不下。
這種問題出現(xiàn)后,往往很棘手,通常是由于應(yīng)用程序不合理造成的,而不合理程序或內(nèi)存泄漏的源頭可能并不明顯。本人的一次經(jīng)歷是,經(jīng)過十多天各種測(cè)試手段后,最后確定問題是由一處String累加引起的,改成StringBuffer就解決了,可見,忽略“小問題”往往會(huì)帶來大麻煩。
三、分析手段
1. 分析GC日志、系統(tǒng)日志
2. 程序中設(shè)置監(jiān)控?cái)帱c(diǎn)
3. 盡可能重現(xiàn)故障并同時(shí)監(jiān)控JVM內(nèi)存,找出引起內(nèi)存急劇上升的規(guī)律
4. 檢查關(guān)鍵程序或頻繁使用的工具類的合理性
四、解決手段
1. 主要從程序入手:降低內(nèi)存使用量;字符串累加時(shí)以StringBuffer代替String;隨時(shí)釋放不再需要的對(duì)象;SQL優(yōu)化及避免頻繁取出大量數(shù)據(jù);Session中不要放大的數(shù)據(jù)。。。
2. 據(jù)WebSphere和WebLogic官方建議:通常情況下JVM的Heap最小值和最大值可設(shè)成一樣(根據(jù)實(shí)際情況調(diào)整),可取系統(tǒng)內(nèi)存的25%-75%,保證JVM有合理足夠的內(nèi)存大小
3. 應(yīng)用服務(wù)器的其他優(yōu)化措施
五、應(yīng)急措施
1. 不設(shè)定JVM的最大Heap上限
2. 程序中判斷內(nèi)存吃緊時(shí)執(zhí)行Runtime.gc()強(qiáng)制垃圾收集,此方式比自動(dòng)收集徹底,可一定程度上改善內(nèi)存利用效率
3. 在不影響業(yè)務(wù)的情況下,定期重啟應(yīng)用服務(wù)器