1. 程式人生 > >Java堆外記憶體溢位問題排查,top命令下java服務res值上升

Java堆外記憶體溢位問題排查,top命令下java服務res值上升

前幾天寫了一套java服務用於對接視訊單位的sdk介面,但是專案環境測試的時候出現了問題:

         在linux環境下使用top命令檢視java命令的mem比值一直在緩慢的增加,第二天出現了服務宕機的情況,生成hs_err的log                   

          測試環境的配置:阿里雲ecs,總實體記憶體7.6g 。 java服務啟動引數xmx為total的7/10

          伺服器上就我這一個吃大記憶體的服務,只有我自己用於測試使用,按照常理來說應該夠用才對。

問題排查過程:

首先確定是否是記憶體溢位的問題 ? 

 過程:使用java自帶的一些命令,jmap ,jstack等命令以及jconsole遠端監控結合gc的日誌進行gc情況的排查,java堆因為記憶體較小              的問題  除了eden的gc頻率比較快一點,其他都在正常課接受範圍之內。   dump下來的記憶體快照用mat分析也沒發現問題。

結論:不是堆記憶體問題!

top命令下檢視到的mem總數 = 系統自身耗記憶體 + java heap + no heap(meta space+code cache 等)*執行緒數 + 虛擬機器程序本身 + 虛擬機器棧(執行緒棧)*執行緒數 + native heap

那麼既然java heap沒有發現問題,再結合服務中使用jna呼叫so,其中so中涉及到大量的socket與緩衝區還有視訊資料的接收處理等

那麼懷疑native heap的使用除了問題?

過程:首先確定下XX:MaxDirectMemorySize的預設值是多少(我沒有顯示的去設定maxSize,關注1.8的時候對直接記憶體的印象還停留在舊版本的預設64m!!!)

經過一番查閱發現 1.8版本最大可以直接記憶體可以使用引數-XX:MaxDirectMemorySize設定,如不設定,預設值為java heap 的max最大值,-Xmx - from區域的大小(幾乎等同xmx)。native heap 達到最大值,不會觸發gc,如果釋放不了足夠的空間,引發宕機的風險。

然後在結合剛才的記憶體分配情況,會出現的記憶體競爭,不宕機才怪,果然!修改完引數3/10之後,專案穩定了很多!至此問題算是圓滿解決!

如果該方案還沒有解決你的問題,那我推薦你使用google-perftools一款google的良心工具,在linux上下載安裝完成後在專案啟動前加上一些啟動引數的配置,就可以經過專案一段時間執行,可以統計出來記憶體異常的程式碼塊了!

有關於下載的連結還有使用方式以及結構化輸出後的引數說明:

如有問題探討,可留言,看到及時回覆!