最近發現有2個odm的服務器經常內存task這個java進程占用內存超過9.2個G 把服務器內存耗盡了,服務器只剩下100-200M 把服務器拖得很卡
先用 jmap -histo 7917 > 7917.txt 排查堆內存有沒有內存泄漏。沒有發現heap中有什么異常很大的對象,total也才3個G
后面發現可能是堆外內存native heap占用過多,這些內存占用不會體現在jmap -histo 命令輸出內容中,只有用top -p 7917 看java進程占用總大小。
后面設置了java啟動參數 -XX:MaxDirectMemorySize=2G 再觀察一下,因為如果XX:MaxDirectMemorySize不設置就默認和xmx一樣的大小6G 可能最后就把機器的內存吃完了
參考如下文章
https://blog.csdn.net/PioneerX_x/article/details/81489702
前幾天寫了一套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,如果釋放不了足夠的空間,引發宕機的風險。
見源碼分析L:http://hllvm.group.iteye.com/group/topic/27945
然后在結合剛才的內存分配情況,會出現的內存競爭,不宕機才怪,果然!修改完參數3/10之后,項目穩定了很多!至此問題算是圓滿解決!
如果該方案還沒有解決你的問題,那我推薦你使用google-perftools一款google的良心工具,在linux上下載安裝完成后在項目啟動前加上一些啟動參數的配置,就可以經過項目一段時間運行,可以統計出來內存異常的代碼塊了!
有關於下載的鏈接還有使用方式以及結構化輸出后的參數說明:
下載地址:https://github.com/gperftools/gperftools
如果操作系統64位還需要先安裝 libunwind庫:http://download.savannah.gnu.org/releases
使用方式和參數詳解:https://blog.csdn.net/turkeyzhou/article/details/8794188
如有問題探討,可留言,看到及時回復!