1 頻繁 FullGC/YongGC
查看 gc 日志
jstat -gcutil pid 查看內(nèi)存使用和 gc 情況
2 代碼消耗,如死循環(huán),md5 等內(nèi)存態(tài)操作
1)arthas (已開(kāi)源:https://github.com/alibaba/arthas)
thread -n 5 查看 CPU 使用率最高的前 5 個(gè)線程(包含堆棧,第二部分有詳解)
2)jstack 查找
ps -ef | grep java 找到 Java 進(jìn)程 id
top -Hp pid 找到使用 CPU 最高的線程
printf ‘0x%x’ tid 線程 id 轉(zhuǎn)化 16 進(jìn)制
jstack pid | grep tid 找到線程堆棧
排查方法見(jiàn)常見(jiàn)問(wèn)題一
2 iowait,等待 IO
vmstat 查看 blocked 進(jìn)程狀況
jstack -l pid | grep BLOCKED 查看阻塞態(tài)線程堆棧
jstack -l pid | grep BLOCKED 查看阻塞態(tài)線程堆棧
profiler dump 線程棧,分析線程持鎖情況
新 new 的對(duì)象放在 Eden 區(qū),當(dāng) Eden 區(qū)滿之后進(jìn)行一次 MinorGC,并將存活的對(duì)象放入 S0;
當(dāng)下一次 Eden 區(qū)滿的時(shí)候,再次進(jìn)行 MinorGC,并將存活的對(duì)象和 S0 的對(duì)象放入S1(S0 和 S1 始終有一個(gè)是空的);
依次循環(huán)直到 S0 或者 S1 快滿的時(shí)候?qū)?duì)象放入 old 區(qū),依次,直到 old 區(qū)滿進(jìn)行 FullGC。
jdk1.7 之前 Java 類(lèi)信息、常量池、靜態(tài)變量存儲(chǔ)在 Perm 永久代,類(lèi)的原數(shù)據(jù)和靜態(tài)變量在類(lèi)加載的時(shí)候放入 Perm 區(qū),類(lèi)卸載的時(shí)候清理;在 1.8 中,MetaSpace 代替 Perm 區(qū),使用本地內(nèi)存,常量池和靜態(tài)變量放入堆區(qū),一定程度上解決了在運(yùn)行時(shí)生成或加載大量類(lèi)造成的 FullGC,如反射、代理、groovy 等。
CMSInitiatingOccupancyFraction 表示老年代使用率達(dá)到多少時(shí)進(jìn)行 FullGC;
UseCMSCompactAtFullCollection 表示在進(jìn)行 FullGC 之后進(jìn)行老年代內(nèi)存整理,避免產(chǎn)生內(nèi)存碎片。
1)survivor 區(qū)太小,對(duì)象過(guò)早進(jìn)入老年代。
jstat -gcutil pid 1000 觀察內(nèi)存運(yùn)行情況;
jinfo pid 查看 SurvivorRatio 參數(shù);
2)大對(duì)象分配,沒(méi)有足夠的內(nèi)存。
日志查找關(guān)鍵字 “allocating large”;
profiler 查看內(nèi)存概況大對(duì)象分布;
實(shí)例數(shù)量前十的類(lèi):jmap -histo pid | sort -n -r -k 2 | head -10
實(shí)例容量前十的類(lèi):jmap -histo pid | sort -n -r -k 3 | head -10
dump 堆,profiler 分析對(duì)象占用情況
1)fgc 觸發(fā)比例過(guò)大,導(dǎo)致老年代占用過(guò)多,并發(fā)收集時(shí)用戶線程持續(xù)產(chǎn)生對(duì)象導(dǎo)致達(dá)到觸發(fā) FGC 比例。
jinfo 查看 CMSInitiatingOccupancyFraction 參數(shù),一般 70~80 即可
2)老年代存在內(nèi)存碎片。
jinfo 查看 UseCMSCompactAtFullCollection 參數(shù),在 FullGC 后整理內(nèi)存
業(yè)務(wù)監(jiān)控
sunfire
eagleeye
日志關(guān)鍵字 “Deadlock found when trying to get lock”
Jstack 或 zprofiler 查看阻塞態(tài)線程
jstack –l pid | grep -i –E 'BLOCKED | deadlock'
dump thread 通過(guò) zprofiler 分析阻塞線程和持鎖情況
mvn dependency:tree 分析報(bào)錯(cuò)方法所在的 jar 包版本,留下新的
arthas:sc -d ClassName
XX:+TraceClassLoading
ClassNotFoundException
NoClassDefFoundError
ClassCastException
-f 跟蹤文件
-i 忽略大小寫(xiě)
-v 反轉(zhuǎn)查找
-E 擴(kuò)展正則表達(dá)式 :grep -E 'pattern1|pattern2' filename
-b 開(kāi)啟并發(fā)
-p 指定并發(fā)數(shù)
-A 開(kāi)啟 askpass
-F 指定分隔符:awk -F “|” '{print $1}‘ | sort -r | uniq -c
時(shí)間段匹配:sed '/2020-03-02 10:00:00/,/2020-03-02 11:00:00/p' filename
dashboard:系統(tǒng)實(shí)時(shí)數(shù)據(jù)面板, 可查看線程,內(nèi)存,gc 等信息
thread:jvm 線程堆棧信息,如查看最繁忙的前 n 線程
getstatic:獲取靜態(tài)屬性值,如 getstatic className attrName 可用于查看線上開(kāi)關(guān)真實(shí)值
sc:查看 jvm 已加載類(lèi)信息,可用于排查 jar 包沖突
sm:查看 jvm 已加載類(lèi)的方法信息
jad:反編譯 jvm 加載類(lèi)信息,排查代碼邏輯沒(méi)執(zhí)行原因
watch:觀測(cè)方法執(zhí)行數(shù)據(jù),包含出入?yún)?,異常等?/p>
trace:方法內(nèi)部調(diào)用時(shí)長(zhǎng),并輸出每個(gè)節(jié)點(diǎn)的耗時(shí),用于性能分析
tt:用于記錄方法,并做回放
1 線程池滿
rpc 框架線程池滿
高 RT 接口進(jìn)行線程數(shù)限流
應(yīng)用內(nèi)線程池滿
重啟可短暫緩解,具體還得看問(wèn)題原因
單機(jī)置換或重啟,可短暫緩解,恢復(fù)看具體原因
集群高且流量大幅增加,擴(kuò)容,恢復(fù)看具體原因
限流
降級(jí)
死鎖
kill 進(jìn)程
慢 sql
sql 限流
聯(lián)系客服