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.
I know this is non-trivial. Here are some starting points for closely related questions:
You can get a (likely unsatisfactory) start by using VirtualQueryEx to determine the memory used by PE files, heaps, etc. Here is one program that provides a Virtual memory map view. This should answer the image size of the device driver.
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 detours to 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.
Good luck.
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).
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.
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.