現象
隨著程式執行,記憶體佔用率越來越高,直到觸發linux的OOM,程式被殺死。
分析工具
執行環境:.net core 3.1(微軟的分析工具要求最低3.0,無法分析2.1的core程式,需要先改為core 3.1才能分析)
linux:ubuntu 18
分析工具:dotnet-counters, dotnet-dump
工具的安裝見:https://docs.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-counters
分析過程
1,獲取要分析程式的pid
使用top或者ps等等工具,獲取程式的pid
對於docker環境,如果沒有安裝top命令,可以使用如下安裝
apt-get install procps
2,檢視記憶體使用情況(我這裡pid為13156)
dotnet-counters monitor -p 13156
從結果來看,GC中的Gen2佔用了較多的記憶體,理論上,不應該有很多的Gen2,我們需要分析一下Gen2裡面到底是什麼?
Gen0,Gen1,Gen2以及LOH的區別,以及.net core記憶體管理機制,見:
https://docs.microsoft.com/en-us/aspnet/core/performance/memory?view=aspnetcore-5.0
3,獲取程式的dump檔案
dotnet-dump collect -p 13156
說明:要使用這條命令獲取dump,如果在docker中,需要提供docker的--private引數,如果是在AWS的ECS中使用的Fargate模式執行,則不支援此引數。需要在EC2上執行。
此命令會在當前目錄生成一個dump檔案
4,分析dump檔案
dotnet-dump analyze core_20210510_054712
# 分析gen2中的內容,每個命令的引數以及和含義,可以使用help檢視
dg gen2
從結果來看,有很多string型別的資料在gen2中,以及mysql的一些資料,我們開啟看看具體是什麼內容
看輸出,有很多一樣的內容,我們隨便開啟一個看看
可以看到內容就是資料庫的返回資料
同樣的方法,我們看看哪些string裡面都是什麼
有非常多的物件,我們也是隨便開啟一個看看內容
看著像是web的列印
總結
獲取dump檔案
dotnet-dump collect <pid>
分析dump檔案
dotnet-analyze xxxxx
獲取gen2或者其他的記憶體資料
dg gen2 | gen1 | gen1 | genloh
檢視記憶體資料型別
dumpheap -mt xxxxxx
檢視記憶體資料的具體內容
do xxxxxx
通過具體內容,配合開發人員定位程式碼問題