首页 > 解决方案 > 了解 .NET 内存管理和分析

问题描述

我有一个 C# 应用程序,它消耗的内存量绝对不足,而且还在稳步增加。我尝试使用 Visual Studio 2019 内存分析器来查找问题。我期待看到某些特定类型的千兆字节对象并找到泄漏,但我发现了一个完全正常的对象集,每种类型不超过 800 KB。

堆快照

快照大小也表明正常堆大小为 8MB,而进程内存接近 5GB!

个人资料截图

我的想法是 GC 出于某种原因拒绝收集未引用的对象,但 GC 标记确实经常出现在内存图表上。我还尝试通过显式调用 GC.Collect() 来清理第 2 代对象。

看起来我不了解内存处理的一些基本概念。我错过了什么?我该怎么做才能找到问题?

UPD:我还发现了一个奇怪的问题。我在我的软件中使用 FluentFtp 客户端,当我在堆中找到这些条目时(我不使用任何其他网络功能)

流利的FTP

我以为我找到了泄漏。这些数字永远不会减少,即使处理线程也无济于事!但是当我将 ftp 代码提取到单独的应用程序时,问题就消失了。

FtpClient client = new FtpClient(<ip>);
client.Credentials = ...
for (int i = 0; i < 1000; i++)
{
   client.Connect();
   client.Disconnect();
}

最后我只有 63 个这样的对象!请注意,私有内存仅比堆大 86 倍,而不是在我的应用程序中为 625。完全相同的代码怎么可能在我的应用程序中产生不同的结果?

FluentFtpProfiling

FluentFtp 堆

标签: c#.netmemory-managementprofiling

解决方案


看起来确实是 FluentFtp 问题。我将其更改为另一个库,一切都恢复了正常。但我仍然知道为什么我不能在单独的应用程序中重现这个问题。


推荐阅读