我用 .NET/C# 编写的应用程序有问题。它由一个服务器组成,该服务器管理一些其他机器,并在它们上运行测试。它是一个 Windows 窗体应用程序。为了以适当的错误处理运行测试,对于每台机器,我有两个线程:一个用于运行测试,一个用于连续 ping 它。每台机器都有一个运行队列,其中存储了任务,这些任务将在该特定机器上运行。
问题是一段时间后,当队列中存在多个任务时,它消耗的内存(进程资源管理器、任务管理器)逐渐从大约 50-100MB 增加到 1.6-1.8 GB。在大约此限制下,几乎所有与远程计算机的事务(共享文件复制、远程 WMI 访问)都会因“存储空间不足”或“内存不足”而失败。我尝试了一些工具来本地化字符串,我得到的最接近的是 .Net Memory Profiler。这并没有太大帮助,因为最大的内存量驻留在“私人数据 - 未识别”中。我猜这是非托管数据,因为我可以评估所有其他数据(从我的程序)到每个字符串和 int,以及它的每个实例。
谁能建议我可以使用的工具来正确定位泄漏并修复它。如果我知道使用该内存的 DLL(来自我的应用程序)/线程,或者至少如果我能以某种方式查看该内存中的内容,那将对我有很大帮助。
注意:很多帖子都关于两个例外:存储空间不足和内存不足。他们中的大多数人建议增加“服务器”机器(在我的例子中是客户端)上的 IRPStackSize。我在所有机器上都有 50(0x32) 的 IRPStackSize,包括服务器。
编辑
关于评论:是的,我确实维护了一个日志,但没有任何奇怪的事情发生。使用内存分析器我发现我的应用程序,当非托管部分超过 1GB 时,.NET 端使用大约 20MB 内存。在 WinDbg 的帮助下,我发现了额外内存中的内容(大部分内容)。为了访问机器并在它们上运行不同的测试,我使用 WMI,我有一个包装器。我使用的所有东西都被释放(使用语句,并且对于一些实际调用 Dispose 方法的人。奇怪的是,内存中充满了这个类的克隆。有谁知道为什么一个类会在内存中克隆自己。
注意:内存使用量增加的速度大约为 5MB/s,因此实际上并不是很长一段时间。我也想知道为什么垃圾收集器没有释放它。我正在使用 C# 类来处理 WMI,而不是 COM,也不是非托管代码。此外,在堆上的对象中,我看到很多属于 wmiutils 的数据,CWbemError。奇怪的是,谷歌甚至不知道这个词(CWbemError 没有结果)