1. 程式人生 > >Java進程內存泄漏判斷及解決方法

Java進程內存泄漏判斷及解決方法

proc 環境 系統日誌 調用 相對 process 容易 進行 fff

  • 內存泄漏種類
    Java使用的內存種類包含三種,這三種類型的內存都可能發生內存泄漏。
    ? 堆內存泄漏,如果JVM 不能在java 堆中獲得更多內存來分配更多java 對象,將會拋出java堆內存不足(java OOM) 錯誤。如果java 堆充滿了活動對象,並且JVM 無法再擴展java 堆,那麽它將不能分配更多java 對象。更多情況是程序設計有問題,生成的對象占用過多的堆內存造成堆內存泄漏。
    ? 本地內存泄漏, 如果JVM 無法獲得更多本地內存,它將拋出本地OOM錯誤。當進程用到的內存到達操作系統的最大限值,或者當計算機用完RAM 和交換空間時,通常會發生這種情況。當發生這種情況時,JVM處於本地內存OOM狀態,此時虛擬機會打印相關信息並退出。本地內存泄漏根本原因是Java調用本地庫或方法,這些本地庫中的API有內存泄漏。
    ? 加載類(字節碼)的Perm內存不足.即指定的Permsize不足以加載系統運行使用的.class字節碼文件,就發發生Perm內存不足的錯誤。
    大多數內存泄漏是JVM堆內存泄漏,下面舉一個堆內存泄漏的分析及解決方法。
  • 問題診斷
    在壓力測試環境,對一Java應用服務進行12小時穩定性壓測,壓測結束後服務器的CPU使用率還很高,使用top使用觀察Java進程使用了720%,機器配置為8C。
    技術分享圖片
    使用jstat命令查看java進程,eden區內存占用了接近100%,老年代占用了99.79%,從FGC列看到JVM在不斷做Full GC操作。
    技術分享圖片
    通過上述分析,可以確定問題的原因是JVM有內存泄漏。
  • 解決問題
    JVM內存泄漏問題的解決相對來說比較簡單。
    (1)使用下面的命令dump出JVM內存映像
    jmap -dump:format=b,file=mydump.bin pid
    生成的dump文件會比較大,比JVM配置的堆大小相當
    (2)使用內存泄漏工具分析這個dump文件,內存泄漏工具有很多,在百度上一搜就能搜到很多,如MemoryAnalyzer.exe。
    從工具分析生成的分析結果可以很容易找到占用內存最多的對象,結合程序分析這個對象在程序中的使用,一般很容易就定位出內存泄漏的原因。
  • 小結
    定位問題和分析問題時下面的工具就可以定位問題和解決問題。
    --linux的top命令
    --JDK自帶的工具jstat和jmap
    --JVM內存泄漏工具
    JVM內存泄漏問題的處理相比C程序內存泄漏更好定位和解決,主要原因是Java有更好用的診斷和分析工具。
    對於本地內存泄漏,上述分析方法就不靈了。本地內存泄漏用JDK的工具(如jstat和jmap)是無法找到原因的。解決這類問題還得用解決C程序內存泄漏的方法多定位和分析,結合操作系統日誌和命令及一些經驗技巧來解決。
  • Java進程內存泄漏判斷及解決方法