【.Net Core】分析.net core在linux下記憶體佔用過高問題

鄭立賽發表於2021-05-10

現象

隨著程式執行,記憶體佔用率越來越高,直到觸發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

通過具體內容,配合開發人員定位程式碼問題

 

相關文章