【发布时间】:2008-12-27 23:10:33
【问题描述】:
如何确定每个设备驱动程序占用了多少内存?我假设这可以通过一些 Win32 或 .NET API 来完成,但我无法确定是哪一个。
【问题讨论】:
标签: windows memory-management driver
如何确定每个设备驱动程序占用了多少内存?我假设这可以通过一些 Win32 或 .NET API 来完成,但我无法确定是哪一个。
【问题讨论】:
标签: windows memory-management driver
Windows 使用池标记跟踪设备驱动程序内存使用情况。如果您知道相关驱动程序传递给ExAllocatePoolWithTag 的池标记,那么您可以使用poolmon(来自Windows Driver Kit)、PoolTag(来自OSR)或WinDbg (or KD) 等工具跟踪其内存使用情况(来自 Windows 调试工具)。
请注意,设备驱动程序可能会调用间接分配内存的内核 API。例如,调用IoAllocateMdl 将导致Windows I/O 管理器使用Windows I/O 管理器分配的不同池标记为内存描述符列表分配内存。因此,代表多个设备驱动程序执行的分配可能都使用相同的池标记。
如果您尝试确定哪个驱动程序正在泄漏内存,请使用 poolmon/PoolTag/WinDbg/KD 识别正在泄漏的池标记。然后将内核调试器(WinDbg 或 KD)附加到系统并将变量 nt!poolhittag 设置为泄漏池标记。下次调用ExAllocatePoolWithTag 以使用该池标记分配内存时,系统将进入内核调试器,然后您可以查看调用堆栈以确定哪个驱动程序正在执行分配。这个过程在Using the Kernel Debugger to Find a Kernel-Mode Memory Leak中有更详细的描述。
【讨论】:
我知道这很重要。以下是密切相关问题的一些起点:
您可以通过使用VirtualQueryEx 确定PE 文件、堆等使用的内存来获得一个(可能不令人满意的)开始。这是一个提供Virtual memory map 视图的程序。这应该回答设备驱动程序的图像大小。
更大的困难在于确定如何标记由分配它的代码动态分配的内存。最好的办法是使用detours 之类的东西来跟踪动态内存分配,并遍历堆栈以确定发起者。最后,您希望为设备驱动程序执行此操作的事实更进一步。我怀疑可以为设备驱动程序使用弯路(尽管我不确定)。我知道从设备驱动程序中遍历堆栈非常重要。
您还可以从SysInternals suite 中的 ProcExp 获取您想要的数据。运行它转到“系统”,转到查看/显示下部窗格,启用 Dll。然后右键单击列标题并添加工作集的标题,例如'WS 总计'。我不确定这可以正确标记它们的内存。在我的盒子上,它为他们提供了设备驱动程序的映射图像大小,但在工作集列中只有 0K。我认为 procexp 没有给出答案是合理的证据,证明解决这个问题不会很快。
祝你好运。
【讨论】: