我在 Windows 中运行的 ASP .NET Core 2.1 应用程序遇到问题,该应用程序增加了内存消耗,直到最终崩溃并需要终止.NET Core Host
过程。我怀疑原因可能是每小时在后台运行一次的同步任务,并且我已确认禁用它可以解决问题。
我一直在使用 VisualStudio 2019 诊断工具分析此同步任务,并且发现了一个我不理解的行为:
正如你所看到的,我拍摄了 3 张快照:
- 同步方法开始时
- 结束同步方法
- 稍后,一旦我们已经存在了范围
在快照表中,我看到了一个对我来说似乎合乎逻辑的行为:堆大小在任务 (2) 期间显着增长,并且在退出作用域 (3) 时几乎减小到初始大小 (1)。然而,“进程内存”图表显示了一个不同的故事:内存消耗增加了,但它永远不会下降。
我已经启动了该应用程序dotnet run
在释放模式下,我在查看所使用的内存时看到了相同的行为.NET Core Host
过程。
我有两个问题:
- 为什么堆大小和进程内存之间存在这种差异?他们不应该有密切的关系吗?
- 这可能是我的网络应用程序崩溃的原因吗?看起来是这样,但内存消耗的增加应该是暂时的,而不是永久性的,直到崩溃为止。我该如何解决它?
Remark:我使用一个简单的 .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
}
}
回答我自己的问题:
- 堆大小在对象创建时增加,在 GC 时减少。当堆大小增加时,进程内存也会增加但当堆大小减小时它不一定会减小。该内存可以保持分配给进程,除非其他进程需要它(机器的可用内存变低),从而强制释放它。该进程不由 GC 处理,GC 在进程级别运行。也可以看看:.NET 进程分配的内存何时释放回 Windows https://stackoverflow.com/questions/5244980/when-is-memory-allocated-by-net-process-released-back-to-windows
- 我发现根本问题是代码中的内存泄漏,一个 while 循环写得不好,修复了崩溃的应用程序。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)