Vla*_*lad 11 linux garbage-collection memory-leaks kubernetes asp.net-core
我有一个websocket服务器,在几天内囤积内存,直到Kubernetes最终杀死它.我们用prometheous-net监控它.
# dotnet --info
Host (useful for support):
Version: 2.1.6
Commit: 3f4f8eebd8
.NET Core SDKs installed:
No SDKs were found.
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.6 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.6 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.6 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Run Code Online (Sandbox Code Playgroud)
但是当我远程连接并进行内存转储(使用createdump
)时,突然内存丢失......没有服务停止,重新启动或丢失任何连接的用户.请参见图中的绿线.
我可以在图表中看到,GC正在各代人中定期收集.
使用以下命令禁用GC Server:
<PropertyGroup>
<ServerGarbageCollection>false</ServerGarbageCollection>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
在禁用GC Server之前,用于以更快的速度增长内存的服务.现在进入512Mb需要两周时间.
在请求/响应方式上使用ASP.NET Core的其他服务不会显示此问题.这使用Websockets,每个连接通常持续大约10分钟......所以我猜想与连接相关的一切都很容易存在到第2代.
请注意,有两个pod,显示相同的行为,然后由于获取内存转储,一个(绿色)突然在内存消息中下降.
没有连接丢失或重新启动.
堆:
(lldb) eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x00007F8481C8D0B0
generation 1 starts at 0x00007F8481C7E820
generation 2 starts at 0x00007F852A1D7000
ephemeral segment allocation context: none
segment begin allocated size
00007F852A1D6000 00007F852A1D7000 00007F853A1D5E90 0xfffee90(268430992)
00007F84807D0000 00007F84807D1000 00007F8482278000 0x1aa7000(27947008)
Large object heap starts at 0x00007F853A1D7000
segment begin allocated size
00007F853A1D6000 00007F853A1D7000 00007F853A7C60F8 0x5ef0f8(6222072)
Total Size: Size: 0x12094f88 (302600072) bytes.
------------------------------
GC Heap Size: Size: 0x12094f88 (302600072) bytes.
(lldb)
Run Code Online (Sandbox Code Playgroud)
免费对象:
(lldb) dumpheap -type Free -stat
Statistics:
MT Count TotalSize Class Name
00000000010c52b0 219774 10740482 Free
Total 219774 objects
Run Code Online (Sandbox Code Playgroud)
这种行为有什么解释吗?
问题是与 RabbitMQ 的连接。因为我们使用的是对活动通道进行排序,所以 RabbitMQ.Client 的“自动重新连接”功能保留了有关死亡通道的大量状态。我们关闭了此配置,因为我们不需要“自动重新连接”功能的“福利”,并且一切都开始正常工作。这很痛苦,但我们基本上必须设置 Windows 部署并使用 Windows 工具(在本例中为 Jetbrains dotMemory)执行常规内存分析过程。使用 lldb 根本没有效率。