【发布时间】:2020-01-27 11:56:14
【问题描述】:
我遇到了在 Windows 中运行的 ASP .NET Core 2.1 应用程序的问题,它增加了内存消耗,直到最终崩溃并需要终止 .NET Core Host 进程。我怀疑原因可能是每小时在后台运行一次同步任务,我已经确认禁用它可以解决问题。
我一直在使用 VisualStudio 2019 诊断工具分析此同步任务,但发现了一个我不理解的行为:
如您所见,我拍摄了 3 张快照:
- 同步方法开始时
- 同步方法结束时
- 稍后,一旦我们已经存在范围
在快照表中,我看到一种对我来说似乎合乎逻辑的行为:堆大小在任务期间显着增长 (2),并且在退出范围 (3) 时几乎减小到初始大小 (1)。然而,“进程内存”图表显示了一个不同的故事:内存消耗增加是存在的,但它从未下降。
我在发布模式下使用dotnet run 启动了应用程序,并且在查看.NET Core Host 进程使用的内存时看到了相同的行为。
我有两个问题:
- 为什么堆大小和进程内存之间存在这种差异?他们不应该密切相关吗?
- 这可能是我的 web 应用程序崩溃的原因吗?看起来是这样,但是内存消耗的增加应该是暂时的,而不是永久的,直到崩溃为止。我该如何解决?
备注:我已经用一个没有依赖关系的简单 .NET Core 控制台应用程序(2.1 和 2.2)重现了相同的行为,因此它没有链接到 ASP 部分或任何其他库:
internal class Program
{
private static void Main()
{
new Whatever().AllocateSomeStrings();
// Snapshot3
Console.ReadKey();
}
}
public class Whatever
{
public void AllocateSomeStrings()
{
// Snapshot1
List<string> numbers = Enumerable.Range(0, 50000).Select(n => n.ToString()).ToList();
// Snapshot2
}
}
【问题讨论】:
-
“我用一个简单的 .NET Core 2.1 控制台应用程序重现了相同的行为,没有依赖关系” – 你能分享一下吗?另外,你能验证这个问题是否仍然出现在 2.2 或 3.0 上?虽然 2.1 作为 LTS 版本仍受支持,但如果知道这是否仍然是当前问题,将会很有趣。
-
那么当它最终崩溃时,它确定是
OutOfMemoryException吗?你观察到这个异常了吗? -
你是在 Linux 上运行这个吗?服务器 GC 通常仅在系统处于内存压力时才释放内存,这在 Linux 上从不发生 - 相反,当内存耗尽时,拥有最多内存的进程将被杀死。
-
回答您的问题:我刚刚在我的问题中添加了简单的控制台应用程序代码。我已经尝试过 2.1 和 2.2,结果相同,但尚未使用 3.0。我在 Windows 上运行。我实际上见过
OutOfMemoryException -
@Luaan,我不确定是否能理解其中的细微差别,也许这会帮助我理解发生了什么:如果我在快照中看到堆大小减小了,这是否意味着GC 释放了那个内存?
标签: c# memory-management .net-core asp.net-core-2.1