在 Windows 中测量设备驱动程序的内存使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/395569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Measuring memory use of device drivers in Windows
提问by Justin R.
How can I determine how much memory each device driver is consuming? I'm assuming this can be done with some Win32 or .NET API, but I just haven't been able to determine which.
如何确定每个设备驱动程序消耗了多少内存?我假设这可以通过一些 Win32 或 .NET API 来完成,但我一直无法确定哪个。
采纳答案by Steve Steiner
I know this is non-trivial. Here are some starting points for closely related questions:
我知道这很重要。以下是密切相关问题的一些起点:
You can get a (likely unsatisfactory) start by using VirtualQueryExto determine the memory used by PE files, heaps, etc. Here is one program that provides a Virtual memory mapview. This should answer the image size of the device driver.
您可以通过使用VirtualQueryEx来确定 PE 文件、堆等使用的内存来获得(可能不满意)的开始。这是一个提供虚拟内存映射视图的程序。这应该回答设备驱动程序的图像大小。
The larger difficulty is in determining how to tag memory that is allocated dynamically by the code that is allocating it. The best shot there is to use something like detoursto track the dynamic memory allocations as they are made and walk the stack to determine the orginator. Finally the fact that you wish to do this for device drivers takes it one step further. I doubt detours can be used for device drivers (though I don't know definitely). I do know walking the stack from a device driver is highly non-trivial.
更大的困难在于确定如何标记由分配内存的代码动态分配的内存。最好的办法是使用诸如绕道之类的东西来跟踪动态内存分配,并遍历堆栈以确定组织者。最后,您希望对设备驱动程序执行此操作这一事实使您更进了一步。我怀疑绕道可用于设备驱动程序(尽管我不确定)。我知道从设备驱动程序中遍历堆栈是非常重要的。
You may also be able to get the data you want from ProcExp in the SysInternals suite. Run it Go to 'System', go to View/show lower pane, enable Dll's. Then right click on the column headers and add the ones for working set e.g. 'WS Total'. I'm not sure what this does to properly label them memory. On my box it gives them mapped image size of device drivers, but simply has 0K in the Working set columns. I take the lack of an answer from procexp as reasonable evidence that solving this problem won't be snap.
您也可以从 SysInternals套件中的ProcExp 获取您想要的数据。运行它 转到“系统”,转到查看/显示下部窗格,启用 Dll。然后右键单击列标题并添加工作集的标题,例如“WS Total”。我不确定这对正确标记他们的记忆有什么作用。在我的盒子上,它为它们提供了设备驱动程序的映射图像大小,但在工作集列中只有 0K。我认为 procexp 没有给出答案作为解决这个问题不会很快的合理证据。
Good luck.
祝你好运。
回答by bk1e
Windows tracks device driver memory usage with pool tags. If you know what pool tags the driver in question passes to ExAllocatePoolWithTag
, then you can track its memory usage using tools such as poolmon
(from the Windows Driver Kit), PoolTag(from OSR), or WinDbg (or KD)(from the Debugging Tools for Windows).
Windows 使用池标记跟踪设备驱动程序内存使用情况。如果您知道有问题的驱动程序传递给哪些池标记ExAllocatePoolWithTag
,那么您可以使用诸如poolmon
(来自 Windows 驱动程序工具包)、PoolTag(来自 OSR)或WinDbg(或 KD)(来自 Debugging Tools for视窗)。
Note that device drivers may call kernel APIs that indirectly allocate memory. For example, calling IoAllocateMdl
will cause the Windows I/O manager to allocate memory for a memory descriptor list, using a different pool tag that is assigned by the Windows I/O manager. Due to this, allocations performed on behalf of multiple device drivers may all use the same pool tag.
请注意,设备驱动程序可能会调用间接分配内存的内核 API。例如,调用IoAllocateMdl
将导致 Windows I/O 管理器使用由 Windows I/O 管理器分配的不同池标记为内存描述符列表分配内存。因此,代表多个设备驱动程序执行的分配可能都使用相同的池标记。
If you're trying to determine which driver is leaking memory, use poolmon/PoolTag/WinDbg/KD identify the pool tag(s) that are being leaked. Then attach a kernel debugger (WinDbg or KD) to the system and set the variable nt!poolhittag
to the leaky pool tag. The next time ExAllocatePoolWithTag
is called to allocate memory with that pool tag, the system will break into the kernel debugger, and then you can look at the call stack to figure out which driver is performing the allocation. This process is described in more detail in Using the Kernel Debugger to Find a Kernel-Mode Memory Leak.
如果您试图确定哪个驱动程序正在泄漏内存,请使用 poolmon/PoolTag/WinDbg/KD 识别正在泄漏的池标记。然后将内核调试器(WinDbg 或 KD)附加到系统并将变量nt!poolhittag
设置为泄漏池标记。下次ExAllocatePoolWithTag
调用该池标记分配内存时,系统将中断内核调试器,然后您可以查看调用堆栈以找出正在执行分配的驱动程序。使用内核调试器查找内核模式内存泄漏中更详细地描述了此过程。