任务管理器与进程资源管理器不一致?

5
我正在尝试追踪我.NET应用程序中的内存泄漏。 Windows任务管理器报告内存使用量保持不变,而Process Explorer报告内存使用量正在增加。
在任务管理器中,我查看唯一的内存列“内存(专用工作集)”。在Process Explorer中,我查看“私有字节”列,因为它正在上升,“工作集”下的值没有上升。
现在,肯定是Process Explorer是正确的,因为经过几次分配后,我的应用程序会崩溃并出现内存不足异常。问题是,为什么任务管理器错误报告应用程序的内存使用情况?不仅如此,它还错误地报告全局系统空闲内存(性能选项卡中的图形保持不变)。 我的代码可能不必要,但为了完整起见,这里是它。它显示一个包含大数组的空窗口。按任何键后,窗口将关闭并打开一个新窗口,其中包含一个新数组。旧窗口已泄漏,可能是由于qt4dotnet GUI库中的错误导致的。
using System;
using com.trolltech.qt.gui;

namespace LeakTest
{
    class Test : QWidget
    {
        public byte[] Data = new byte[1000 * 1000 * 100];

        public Test()
        {
            show();
            GC.Collect(); // so measurements are more accurate
        }

        protected override void keyPressEvent(QKeyEvent arg__1)
        {
            disposeLater();
            new Test();
        }

        [STAThread]
        static void Main(string[] args)
        {
            QApplication.initialize(args);

            new Test();

            QApplication.exec();
        }
    }
}

操作系统: Windows 7

有趣的注释: 当我将“Data”设置为一个维度为[1000 * 1000 * 100][1]的二维分割数组时,任务管理器确实会报告内存使用量的上升。


1
我强烈反对使用任务管理器/进程资源监视器来查找.NET内存泄漏。通常,我使用ANTS Memory Profiler,即使是使用这样一种专业工具,也很难找到泄漏。如果我只使用任务管理器,过去我根本没有机会找到我的泄漏问题。 - Uwe Keim
1
从未使用过的页面不需要任何支持,因为它们在首次访问时可以被置零。因此,它们计入私有字节,但不需要任何RAM,并且不属于工作集。 - CodesInChaos
@CodeInChaos:啊,这解释了很多问题。 - Stefan Monov
2个回答

8
它们是两个完全不同的内存度量。 工作集是程序使用的RAM数量。 它是一个不断变化的数字,并受到其他进程需要多少RAM的影响。 你不能用尽RAM,Windows通过将映射的页面交换到分页文件中使RAM可用于你。
私有字节是你的程序使用的任何其他进程都没有共享的虚拟内存量。 在32位机器上,您有2 GB的虚拟内存可用。 它需要在代码和数据之间共享。 当可寻址的虚拟内存空间不足以容纳请求的分配时,会发生OOM。 是的,这是更准确的数字。
一次要求100兆字节很冒险。 虚拟内存空间可能会被分段,一段时间后可能仍有大量的空闲虚拟内存,但没有足够大的空洞来容纳100兆字节。 嵌套数组解决了这个问题,因为它是一个数组的数组,所需的块要小得多,因此可以轻松地适应剩余的任何空洞。
64位操作系统完全解决了这个问题。 您的程序有许多千兆字节的地址空间可用,实际上仅受分页文件的最大大小限制。 你根本无法用完大的空洞。

1
如果你想追踪内存泄漏,但是通过阅读代码找不到问题所在,那么你可能需要一个专门用于此类工作的真正工具。
任务管理器和进程资源管理器都不适合调试内存泄漏 - 你需要一些能够告诉你哪里分配了未被释放的内存的工具。

1
@Uwe 当然!在像 .net 这样的 GC 系统中,即使有一个出色的工具,追踪它们也可能非常困难。 - David Heffernan
@Uwe Keim: 是的,我实际上也在使用 dotTrace Memory Profiler,但我无法理解它告诉我的内容(因为我正在通过.NET使用C++库的Java绑定),所以我首先尝试了不使用分析器尽可能多地理解情况。后来我偶然发现了这种无法解释的行为,于是我发布了这个问题。我可能会针对该分析器发布另一个问题。 - Stefan Monov
@Stefan 试试ANTS Memory Profiler吧,这是我迄今为止使用过的最好的工具,也许它能帮助你解决问题。 - Uwe Keim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接