服務器的JAVA進程使用的內存是否正常linux
服務器中,JAVA進程的內存佔用= JVM內存+ JAVA堆最大內存大小(Xmx)+JAVA堆外內存大小+棧區( 線程數* Xss)程序員
最須要關注:web
1., 服務器內存是否夠JAVA進程開銷json
坑點: 每次JAVA的啓動,只是檢查當前linux的RES內存, 並不會檢查申請的內存大小。服務器
如, 服務器內存16G ,JAVA進程A的最大堆內存10G, JAVA服務B最大堆內存也是10G, 兩個服務都能正常運行,但一段時間後會被服務器kill掉併發
詳情見我另外一篇 http://www.javashuo.com/article/p-ncatmvmp-md.html .net
2, 是否用到了服務器的SWAP線程
坑點:若是JAVA進程的垃圾回收用到了SWAP,將致使GC時間異常久,服務器上建議關掉SWAP(保證內存夠用狀況下)日誌
詳情見我另外一篇 http://www.javashuo.com/article/p-ffcsaagf-he.html netty
GC是否正常
在啓動JAVA時,注意配置:
JAVA的垃圾回收日誌及地址
-XX:+PrintGCDetails -Xloggc:/data/log/gclog/web_gc_log.txt
JAVA崩潰快照以及地址配置
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/log/dump/
關注GC頻率是否正常
GC 的回收頻率和內存大小掛鉤,通常正常狀況下不多FGC。能夠結合參數配置 GC垃圾回收日誌分析
用 jstat -gc pid 觀察FGC的次數
是否產生了FGC
上次FGC產生的緣由
jstat -gccause
FGC產生的緣由:
堆外內存對象大小,回收是system.gc. 是否禁用(引發FGC)
堆的碎片過多形成FGC(能夠增長每次GC後整理參數)
OC的內存不夠用
promotion failed引發FGC ( 對象晉升失敗)
concurrent mode failure引發FGC(對象晉升時,正在CMS)
持久代大小不夠( jmap -permstat )
堆的碎片過多形成FGC (碎片整理, -XX:CMSFullGCsBeforeCompaction=1 設置多少次full gc後進行內存壓縮)
堆外內存對象大小,回收是system.gc. 是否禁用(-XX:-+DisableExplicitGC)
JVM內存關注點
監控JAVA進程 年輕代(edu):年老代:(ou) 持久代(G1元): 堆外內存大小
總覽
jstat -gc / -gcutil pid
jmap -heap
(這樣沒有堆外內存大小,對外內存若是超過閥值也會調用system.gc進行形成FGC,因此也須要關注. 這個就須要JMX)
時刻掌握本身系統中的具體內存使用狀況,是哪些對象在消耗內存,不要等泄漏再來看
jmap -histo pid , 查看存活對象
查看perm: jmap -permstat
dump內存分析
jmap -dump:format=b,file=dump dump整個內存
時刻關注內存的異常
內存泄漏排查:
當發生了內存泄漏時進行內存快照分析排查
詳情案例見我另外一篇 http://www.javashuo.com/article/p-fimpzluo-s.html
堆外內存的回收是調用system.gc. 是否禁用(引發FGC)
-XX:-+DisableExplicitGC
這裏也有個問題,若是用到了堆外內存(特別注意開源項目如netty),是否禁用了System.gc, 若是禁用。非堆內存會內存泄漏
我遇到過的坑分享
1,inter()的使用形成 (如fastjson) 引發的YGC時間愈來愈久
2, RPC調用用BIO作, 接收對象太大,結果併發上來,形成的GC
3, 半夜預定任務,而後產生了大對象引發的GC,形成了調用服務的TIMEOUT
先到這,還有堆外內存(主要netty)和finalize的兩塊研究先預留欠帳,後續加上
最後:
養成時常關注系統的GC頻率,和dump出快照分析是哪些對象在使用了咱們的內存,而不是等內存溢出纔去分析。
做爲個程序員須要對本身系統的每塊內存作到了如指掌
歡迎關注個人公衆號,重現線上各類BUG, 一塊兒來構建咱們的知識體系