小编Lem*_*Sky的帖子

GC不会释放内存,但会导致托管内存减少和非托管内存增加

我有一个在 Linux 上运行的 ASP.NET Core 应用程序(在 Docker 中,在 Kubernetes 上)。我遇到这样的情况:我的完全托管应用程序在 GC 堆上使用 5 MB,但应用程序保留 5 GB(并且将消耗更多,直到通过 OOM 终止)。我使用 dotMemory 收集了内存转储,可以看到内存被非托管内存消耗。GC.GetTotalMemory我通过调用vs得到了相同的图片Process.GetCurrentProcess().WorkingSet64

在此输入图像描述

该代码是完全托管的,主要是读取文件、处理文件并将处理后的数据存储在数据库中。我使用过DevArt.PostgreSql,但也尝试过Npgsql,但没有什么区别。我还使用单个原始的持久Socket连接。在给定的测试用例中,没有调用 ASP.NET Core 上的 Web API。dotMemory在这些库中以及我的代码部分中都没有显示任何托管泄漏。

内存使用情况将如下所示:

Process.GetCurrentProcess().WorkingSet64=582 MB / GC.GetTotalMemory=372 MB

过了一会儿跳到

Process.GetCurrentProcess().WorkingSet64=600 MB / GC.GetTotalMemory=5 MB

我可以使用以下代码强制执行此集合:

GC.Collect(2, GCCollectionMode.Forced, true, true);
GC.WaitForPendingFinalizers();
GC.Collect(2, GCCollectionMode.Forced, true, true);
Run Code Online (Sandbox Code Playgroud)

因此,我可以得出结论,超过 300 MB 的数据从 GetTotalMemory 转移到了workingSet64。我不知道还有什么办法可以得出这些数字。当内存再次填满时,它可能看起来像这样:

Process.GetCurrentProcess().WorkingSet64=1375 MB / GC.GetTotalMemory=4 MB
(few moments later)
Process.GetCurrentProcess().WorkingSet64=1433 MB / GC.GetTotalMemory=1081 MB
Run Code Online (Sandbox Code Playgroud)

在这种情况下,可以从WorkingSet中回收大量GC内存。然而,这个循环永远不会完美,WorkingSet64 …

.net linux memory garbage-collection kubernetes

7
推荐指数
0
解决办法
949
查看次数

标签 统计

.net ×1

garbage-collection ×1

kubernetes ×1

linux ×1

memory ×1