回覆列表
  • 1 # 小哇說互聯

    某Java服務(假設PID=10765)出現了OOM,最常見的原因為:有可能是記憶體分配確實過小,而正常業務使用了大量記憶體某一個物件被頻繁申請,卻沒有釋放,記憶體不斷洩漏,導致記憶體耗盡某一個資源被頻繁申請,系統資源耗盡,例如:不斷建立執行緒,不斷髮起網路連線一、確認是不是記憶體本身就分配過小方法:jmap -heap 10765二、找到最耗記憶體的物件方法:jmap -histo:live 10765 | more三、確認是否是資源耗盡工具:pstreenetstat檢視程序建立的執行緒數,以及網路連線數,如果資源耗盡,也可能出現OOM。 這裡介紹另一種方法,透過/proc/${PID}/fd/proc/${PID}/task可以分別檢視控制代碼詳情和執行緒數。

  • 2 # ksfzhaohui

    要快速定位無非就三步:dump記憶體檔案,記憶體分析工具生成記憶體洩露分析報告,根據報告到程式碼中分析相關程式碼;

    1.dump記憶體檔案

    ./jmap -dump:format=b,file=heap.hprof pid

    2.記憶體分析

    常用的記憶體分析工具如:MemoryAnalyzer,jprofiler;工具會幫助我們快速的生成一份記憶體洩露分析報告,大致如下所示:

    可以根據上面的問題描述去相關程式碼中,然後進行程式碼分析;

    3.程式碼分析

    在程式碼分析之前,我們大概理一下都會有哪些情況出現OOM;大體上可以分為幾類類情況:JVM本身分配的記憶體過小,分配的記憶體不小程式碼可最佳化,分配的記憶體不小存在記憶體洩漏;

    1.JVM本身分配的記憶體過小

    這種情況一般比較少見,一般配置記憶體至少1G記憶體以上;常見的比如查詢資料庫幾十條,上百條資料記憶體就不夠用了,加記憶體可以立馬能解決問題的;

    2.分配的記憶體不小程式碼可最佳化

    這種問題就比較常見了,記憶體本身配置的並不小,但是出現OOM;

    常見的比如以下查出幾千上萬條資料庫記錄,導致記憶體不夠用,這種情況可以分批次查詢;

    本地快取,但是沒有提供清除策略,導致記憶體越來越大,這時候需要指定清除策略比如lru策略;

    匯入一個檔案比如excel,一下全部載入到記憶體中,導致記憶體OOM,這時候可以換一種讀取的方式,透過流讀取方式;

    3.分配的記憶體不小存在記憶體洩漏

    這種問題就比較難發現了,開發者任務應該清除的記憶體並沒有清除,一直存在記憶體中,導致資料越積越多,最終導致記憶體OOM;常見的比如hashset因為修改計算hash值的資料導致記憶體洩漏;

    本人之前遇到過的記憶體溢位分析實戰:

    Poi讀取Excel引發的記憶體溢位

    https://www.toutiao.com/i6748971979136565764/

  • 中秋節和大豐收的關聯?
  • 兒童幾歲才能自理?