任务管理器不同意Process Explorer?

Ste*_*nov 3 .net windows memory-leaks taskmanager process-explorer

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

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

现在,当然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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

操作系统:Windows 7

有趣的说明:当我将"数据"作为2D锯齿状维度数组时[1000 * 1000 * 100][1],任务管理器报告提高内存使用量.

Han*_*ant 6

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

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

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

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