c# - 非托管内存未显示在任务管理器中

标签 c# unmanaged

我写了下面的测试(实际用在更广泛的上下文中)

IntPtr x = Marshal.AllocHGlobal(100000000);

Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);

Marshal.FreeHGlobal(x);

Console.ReadKey(true);

为什么任务管理器在第一次按键之前没有显示任何已分配 100 兆字节的迹象?如果这是设计使然,我还能如何测试非托管堆内存的消耗?

最佳答案

您对操作系统的工作原理有了一些了解。此行为并非特定于 Marshal.AllocHGlobal(),例如尝试此代码:

    static void Main(string[] args) {
        var arr = new byte[100000000];
        Console.ReadKey(true);
    }

默认情况下,任务管理器会显示您使用了多少 RAM。但是您的操作系统与许多其他操作系统一样,是一个请求分页的虚拟内存操作系统。你还没有要求任何东西。您所做的只是分配虚拟内存。只是地址空间,它在这个测试中保持虚拟,只是处理器的编号。每 4096 字节一个。在您实际访问数组之前,需求不会发生。添加:

        for (int ix = 0; ix < arr.Length; ix += 4096) {
            byte dummy = arr[ix];
        }

Bam,现在你看到它放大了。不一定到 100 兆字节,但大多数机器现在有足够的 RAM,不需要将任何页面换回页面文件来提供足够的存储空间。

否则这是一个很好的提醒,为什么任务管理器不是一个很好的内存分析器。您的程序消耗多少 RAM 是无关紧要的。如果你使用太多,那么你会注意到它,你的程序会变慢很多。

任务管理器可以显示原始代码的副作用,您必须添加“提交大小”列。在早期的 Windows 版本中命名不同,模糊内存,我认为它是 VM 大小。提交大小衡量页面文件中保留了多少空间。地址空间的备份存储,保留以便在操作系统需要取消映射页面以在其他地方提供 RAM 时存储 RAM 内容。 Windows 不允许过度使用内存,当 64 位程序不能足够快地增长页面文件时,这是您获得 OOM 的方式。

关于c# - 非托管内存未显示在任务管理器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49333416/

相关文章:

c# - 在 C# 中捕获应用程序窗口的最佳方法是什么?

具有非托管 DLL 的 C# 应用程序卡住整个系统

c# - 如何以编程方式测试 cookie?

c# - 在运行时使用和调用 SOAP Web 服务 - 来自 WSDL 文件的动态 Web 服务客户端

c# - WCF 服务基址与端点地址

c# - WinApi - GetLastError 与 Marshal.GetLastWin32Error

.NET - 从非托管阵列复制到非托管阵列

c# - 使用 C#,如何检查计算机帐户是否在事件目录中被禁用?

c# - 具有已知键列表的延迟加载缓存的多线程实现

c# - WM_COPYDATA 从 C++ 到 C#