Detecting Increase in Heap Allocations with UMDH
The user-mode dump heap (UMDH) utility works with the Windows operating system to analyze the heap allocations for a specific process. UMDH utility is used to locate which routine in a specific process is leaking memory.
- Download and install the UMDH utility for Windows OS. For more information, see Debugging Tools for Windows from Microsoft documentation.
-
Enable "Create user mode stack trace database" with gflags.exe -i bwappnode-umdh.exe +ust command. Get the process name from task manager.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>gflags.exe -i bwappnode-umdh.exe +ust Current Registry Settings for bwappnode-umdh.exe executable are: 00001000 ust - Create user mode stack trace database
- Before using UMDH, you must have access to the proper symbols for your application. UMDH uses the symbol path specified by the environment variable _NT_SYMBOL_PATH. Set the variable to a path containing symbols for your application.
If you also include a path to Windows symbols, the analysis is more complete. The syntax for this symbol path is the same as that used by the debugger.
For more information, see Symbol Path for Windows Debugger from Microsoft documentation.
For example, if the symbols for your application are located at C:\MySymbols, then to use the public Microsoft symbol store for your Windows symbols, using C:\MyCache as your downstream store, run the following command to set your symbol path:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>set _NT_SYMBOL_PATH=c:\mysymbols;srv*c:\mycache*https://msdl.microsoft.com/download/symbols
- Procedure
- Determine the process ID (PID) for the process to investigate.
For more information, see Finding the process ID from Microsoft documentation.
- Analyze the heap memory allocations for the process before the memory leak is detected, and save it to a log file.
- Collect the data at application start up before sending load.
For example, if the PID is 5872, and name of the log file is log_before.txt, use the following command:
umdh.exe -p:5872 -f:log_before.txt
- Use the UMDH utility to analyze the heap memory allocations for this process after the memory starts increasing, and save it to a log file.
- Collect this data at regular intervals when an application starts leaking memory.
For example, if the PID is 5872, and name the log file is log_after.txt, use the following command:
umdh.exe -p:5872 -f:log_after.txt
- The UMDH utility can compare two different log files and display the change in their respective allocation sizes. To redirect the results into a third text file, use the greater-than symbol (>). To convert the byte and allocation counts from hexadecimal to decimal, use the -d option.
For example, to compare log_before.txt and log_after.txt files, and save the results to the file log_compare.txt, use the following command:
umdh.exe -d log_before.txt log_after.txt > log_compare.txt
- For each call stack that is labeled as "BackTrace" in the UMDH log files, there is a comparison made between the two log files. The snippet of the output is as follows:
// where: // BYTES_DELTA - increase in bytes between before and after log // NEW_BYTES - bytes in after log // OLD_BYTES - bytes in before log // COUNT_DELTA - increase in allocations between before and after log // NEW_COUNT - number of allocations in after log // OLD_COUNT - number of allocations in before log // TRACEID - decimal index of the stack trace in the trace database // (can be used to search for allocation instances in the original // UMDH logs). + 8856 ( 18400 - 9544) 12 allocs BackTrace5 + 3 ( 12 - 9) BackTrace5 allocations ntdll!RtlpAllocateHeap+2298 ntdll!RtlpAllocateHeapInternal+727 MSVCR100!malloc+5B jvm!JVM_ResolveClass+387AE jvm!???+0 : 53C415D6 jvm!JVM_GetManagementExt+6A5FF jvm!JVM_GetManagementExt+786B1 jvm!JVM_GetManagementExt+7A162 jvm!JVM_GetManagementExt+CA4E jvm!JVM_FindSignal+178329 jvm!JVM_FindSignal+1792E4 jvm!JVM_FindSignal+179491 jvm!JVM_FindSignal+17969F jvm!JVM_GetManagementExt+82712 jvm!JVM_GetManagementExt+8305F jvm!JVM_ResolveClass+5F5FF jvm!JVM_FindSignal+68FA MSVCR100!endthreadex+43 MSVCR100!endthreadex+DF KERNEL32!BaseThreadInitThunk+14 ntdll!RtlUserThreadStart+21
This UMDH output shows that there were 8856 total bytes allocated from the call stack.