8

如何确定每个设备驱动程序消耗多少内存?我假设这可以通过一些 Win32 或 .NET API 来完成,但我无法确定是哪一个。

4

2 回答 2

11

Windows 使用池标记跟踪设备驱动程序内存使用情况。如果您知道有问题的驱动程序传递给什么池标记ExAllocatePoolWithTag,那么您可以使用诸如poolmon(来自 Windows 驱动程序工具包)、PoolTag(来自 OSR)或WinDbg(或 KD)(来自 Debugging Tools for视窗)。

请注意,设备驱动程序可能会调用间接分配内存的内核 API。例如,调用IoAllocateMdl将导致 Windows I/O 管理器使用由 Windows I/O 管理器分配的不同池标记为内存描述符列表分配内存。因此,代表多个设备驱动程序执行的分配可能都使用相同的池标记。

如果您尝试确定哪个驱动程序正在泄漏内存,请使用 poolmon/PoolTag/WinDbg/KD 识别正在泄漏的池标记。然后将内核调试器(WinDbg 或 KD)附加到系统并将变量设置nt!poolhittag为泄漏池标记。下次ExAllocatePoolWithTag调用该池标记分配内存时,系统将进入内核调试器,然后您可以查看调用堆栈以确定哪个驱动程序正在执行分配。此过程在使用内核调试器查找内核模式内存泄漏中有更详细的描述。

于 2009-01-08T07:49:24.657 回答
1

我知道这不是微不足道的。以下是密切相关问题的一些起点:

您可以通过使用VirtualQueryEx确定 PE 文件、堆等使用的内存来获得一个(可能不令人满意的)开始。这是一个提供虚拟内存映射视图的程序。这应该回答设备驱动程序的图像大小。

更大的困难在于确定如何标记由分配它的代码动态分配的内存。最好的方法是使用detours之类的东西来跟踪动态内存分配,并遍历堆栈以确定发起者。最后,您希望为设备驱动程序执行此操作的事实更进一步。我怀疑可以为设备驱动程序使用弯路(尽管我不确定)。我知道从设备驱动程序中遍历堆栈是非常重要的。

您还可以从 SysInternals套件中的 ProcExp 获取您想要的数据。运行它转到“系统”,转到查看/显示下部窗格,启用 Dll。然后右键单击列标题并添加工作集的标题,例如“WS Total”。我不确定这可以正确标记它们的内存。在我的盒子上,它为他们提供了设备驱动程序的映射图像大小,但在工作集列中只有 0K。我认为 procexp 没有给出答案是合理的证据,证明解决这个问题不会很快。

祝你好运。

于 2008-12-27T23:46:50.107 回答