任务管理器不同意Process Explorer?

时间:2011-02-04 20:02:29

标签: .net windows memory-leaks taskmanager process-explorer

我正试图在我的.NET应用程序中追踪内存泄漏。 Windows任务管理器报告内存使用率保持不变,而Process Explorer报告内存使用率正在提高。

在任务管理器中,我正在寻找唯一的内存列,“内存(私有工作集)”。在Process Explorer中,我正在查看“Private bytes”列,因为它正在提升,而“Working set”下的值则没有。

现在,当然Process Explorer是正确的,因为经过多次分配后,我的应用程序崩溃了 Out of memory 异常。问题是,为什么任务管理器误报了应用程序的内存使用情况?不仅如此,它还误报了全局系统的可用内存(“性能”选项卡中的图形保持不变)。

我的代码不应该被需要,但这里是为了完整性。它显示了一个包含大数组的空窗口。当按下任何键时,窗口关闭并打开一个新窗口,并保持一个新阵列。旧窗口已泄露,可能是由于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

有趣的提示:当我将“数据”设为尺寸为[1000 * 1000 * 100][1]的2D锯齿状数组时,任务管理器报告提高内存使用量。

2 个答案:

答案 0 :(得分:6)

它们是两种完全不同的记忆措施。工作集是程序使用的RAM量。它是一个不断变化的数字,受其他进程需要多少RAM的影响。您不能用完RAM,Windows可以通过将映射页面交换到页面文件来使RAM可用。

专用字节数是指程序使用的虚拟内存量,不与任何其他进程共享。在32位计算机上,您可以使用2 GB的虚拟内存。它需要在代码和数据之间共享。当可寻址的虚拟内存量中没有足够的空间来满足所请求的分配时,您将获得OOM。是的,这是更准确的数字。

一次要求100兆字节是有风险的。虚拟内存空间可能会碎片化,过了一段时间后,可能仍有大量的免费虚拟内存,但不是一个足以容纳100兆字节的漏洞。锯齿状数组解决了这个问题,因为它是一个数组数组,所需的块更小,所以可以很容易地适应任何剩下的孔。

64位操作系统完全解决了这个问题。您的程序有许多千兆字节的可用地址空间,实际上仅受页面文件的最大大小限制。你根本无法用完大洞。

答案 1 :(得分:1)

如果您想要追踪内存泄漏,并且通过阅读代码找不到它,那么您可能需要一个专为此工作而设计的真实工具。

任务管理器和Process Explorer都不是用于调试内存泄漏的适当工具 - 您需要一些能够告诉您分配未返回内存的位置。