【.Net Core】分析.net core在linux下內存佔用過高問題

  • 2021 年 5 月 10 日
  • 筆記

現象

隨着程序運行,內存佔用率越來越高,直到觸發linux的OOM,程序被殺死。

分析工具

運行環境:.net core 3.1(微軟的分析工具要求最低3.0,無法分析2.1的core程序,需要先改為core 3.1才能分析)

linux:ubuntu 18

分析工具:dotnet-counters, dotnet-dump

工具的安裝見://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內存管理機制,見:

//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

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