最近給系統做了一點優化,前幾天去檢視系統監控,想看看上線前後cpu使用率曲線變化情況。檢視的時候意外發現上線前後記憶體占用相差不少,20%以上。
本來我沒怎麼在意這個問題,因為我們系統會在執行過程中快取部分資料內容。但客戶覺得有異常,堅持要查。於是把乙個月的記憶體使用情況調出來看,這一看就發現問題了:
系統記憶體占用確實是在緩慢增加,一兩天的記憶體使用率曲線看不出什麼,但乙個月的可以明顯看出來,是一條斜率很小的直線。
發現了有記憶體洩漏,但是想具體分析是哪個程序洩漏的還真不好辦。因為我們系統有上千個程序在跑,而監控系統又只記錄了總體記憶體占用情況,沒記錄單個程序記憶體占用。
沒有槍,沒有炮,只能自己來造 :) 。 我設計了乙個簡單的分析方法:
1 首先,我寫乙個指令碼,每天定期記錄系統所有程序使用情況,儲存到檔案,以時間戳命名。(用ps實現)
2 指令碼跑幾天後,我再使用另乙個指令碼,把檔案合併起來分析,把每個程序在不同時間點的記憶體使用情況合併成一行,逐個程序輸出
3 比較每個程序第一次出現與最後一次出現時占用記憶體之差,按從小到大排序,即可得出可能存在記憶體洩漏的程式。
效果如下:可以看出這個程序記憶體占用一直在增加,從第一次統計到最後一次統計之間記憶體使用增加了1460k
知道問題後就好辦了,使用valgrind+gdb很快就找出導致記憶體洩漏的**,糾正即可。
下面是分析過程中用到的指令碼,希望對大家有幫助
1 # 20190228hch 輔助分析程式記憶體洩漏情況的指令碼
2# 設計思路:首先用ps定期採集所有程式占用記憶體情況,生成多個檔案。然後使用awk分析ps輸出的檔案,把相同程序占用的記憶體合併成一行輸出
3# 計算程序第一次和最後一次出現的時間點占用記憶體之差,逆序輸出即可獲得疑似記憶體洩漏的程式45
# 首先使用以下指令碼採集程式每一分鐘記憶體占用資訊,採集若干分鐘
6 # while [ 1 ]; do
ps -eo '
pid,comm,rsz,vsz,user,comm,args,pcpu,pmem
' --sort rsz > ps_info_$(date
"+%y%m%d%h%m%s
").txt ; sleep
60; done78
# 使用awk指令碼分析記憶體占用資訊 把程序每乙個時間點的記憶體占用情況合併成一行方便對比
9# 並且統計程序第一次出現和最後一次出現占用記憶體差,輸出
10awk'26
}27}28
}2930 v_pid_name = $2"-
" $1"-
" $5; #程式名-程序號-使用者名稱
31 # 非第乙個檔案,第一次出現,需要補齊","
32if (v_file_cnt != 1 && v_mp_pid_cnt[v_pid_name] == 0
) 36
37# rsz是物理記憶體 單位k
38 v_mp_pid_rsz[v_pid_name] = v_mp_pid_rsz[v_pid_name] "
," $3
39# 記錄最後值和初始值 方便後面分析(有需要可以改成最大和最小值)
40#if ($3 > v_mp_pid_rsz_max[v_pid_name]) v_mp_pid_rsz_max[v_pid_name] = $3;
41 v_mp_pid_rsz_max[v_pid_name] = $3;42
if (v_mp_pid_rsz_min[v_pid_name] == 0 ) # || $3
43 v_mp_pid_rsz_min[v_pid_name] = $3;44
45# vsz是虛存 單位k
46 v_mp_pid_vsz[v_pid_name] = v_mp_pid_vsz[v_pid_name] "
," $4
47 v_mp_pid_vsz_max[v_pid_name] = $4;48
if (v_mp_pid_vsz_min[v_pid_name] == 0 ) # || $4
49 v_mp_pid_vsz_min[v_pid_name] = $4;50
51# 在本檔案出現過就標記一下,後面檔案處理完後才知道哪些程序沒出現
52 v_mp_pid_cnt[v_pid_name] =v_file_cnt;53}
54end
60 }'
$(ls -rt ps_inf*txt) > ps_trace.txt #按時間逆序分析
6162
# 將分析結果排序輸出
63 # sh ps_trace.sh; sork -k2n ps_trace.txt | tail -100
乙個記憶體洩漏問題的排查
監控的mem一直居高不下 使用jstat命令檢視gc的情況,發現ygc已經停止,一直在fgc,懷疑記憶體已經洩漏,堆記憶體中有大量無法 的物件。然後檢視gc日誌,發現年輕代和老年代使用率達到99 且full gc後記憶體沒有被 確定肯定是有物件無法被 需要解密的資料 這是加解密的功能,每次執行加解密...
乙個很難發現的記憶體洩漏
當你的資源釋放以後,再去訪問時,就會出現各種錯誤,比如物件返回空,資源不存在等等,這些錯誤都是編譯的時候語法合理的,但是一旦執行到了這裡,肯定就會出錯了 這一塊如果沒被執行的話,還是發現不了錯誤的 而且很難找到這個錯誤的原因 不在於這個錯誤有多麼的難,而是 太多,關係太複雜,沒有很好地條理去分析,邏...
分享乙個ssh打通的指令碼
分享乙個ssh打通的指令碼,經過測試可用。目前只能單向打通,且要求本地使用者名為admin 寫入 可簡單修改 本身只是個人使用,故通用性 異常情況考慮不多,大家可以做個參考。補充一點,important tip authorized keys檔案的許可權很重要,如果設定為777,那麼登入的時候,還是...