Saturday, May 19, 2018

Debug processes with high memory usage

When a process erroneously holds on to excessive memory and not release it, it could eventually lead to under performance or crash. If the memory is being held in heap, try the following:

1. Get a process dump
2. Analyze the process in Windbg by running the following commands

!address -summary
!heap -s
!heap -stat -h <heap address>
!heap -flt s <size>
!heap -p -a <memory address>

!address -summary
0:000> !address -summary
Building memory map: 00000000Building memory map: 00010000
Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...

--- Usage Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
Heap                                    790          5adf9000 (   1.420 GB)  74.95%   71.00%
Stack                                   840          11800000 ( 280.000 MB)  14.43%   13.67%
<unknown>                              1325           81f6000 ( 129.961 MB)   6.70%    6.35%
Free                                    949           6c04000 ( 108.016 MB)            5.27%
Image                                   767           4a7d000 (  74.488 MB)   3.84%    3.64%
TEB                                     280            118000 (   1.094 MB)   0.06%    0.05%
Other                                    58             67000 ( 412.000 kB)   0.02%    0.02%
PEB                                       1              1000 (   4.000 kB)   0.00%    0.00%

--- Type Summary (for busy) ------ RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_PRIVATE                            3188          73d7b000 (   1.810 GB)  95.54%   90.50%
MEM_IMAGE                               789           4cc0000 (  76.750 MB)   3.96%    3.75%
MEM_MAPPED                               84            9b1000 (   9.691 MB)   0.50%    0.47%

--- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal
MEM_COMMIT                             3168          5fa20000 (   1.494 GB)  78.88%   74.72%
MEM_RESERVE                             893          199cc000 ( 409.797 MB)  21.12%   20.01%
MEM_FREE                                949           6c04000 ( 108.016 MB)            5.27%

--- Protect Summary (for commit) - RgnCount ----------- Total Size -------- %ofBusy %ofTotal
PAGE_READWRITE                         1878          5a623000 (   1.412 GB)  74.55%   70.61%
PAGE_EXECUTE_READ                       232           2b4a000 (  43.289 MB)   2.23%    2.11%
PAGE_READONLY                           436           2289000 (  34.535 MB)   1.78%    1.69%
PAGE_READWRITE|PAGE_GUARD               560            47b000 (   4.480 MB)   0.23%    0.22%
PAGE_WRITECOPY                           61            1a4000 (   1.641 MB)   0.08%    0.08%
PAGE_EXECUTE_READWRITE                    1              b000 (  44.000 kB)   0.00%    0.00%

--- Largest Region by Usage ----------- Base Address -------- Region Size ----------
Heap                                        1a6b0000            fd0000 (  15.813 MB)
Stack                                        1a60000             fd000 (1012.000 kB)
<unknown>                                   7f0e0000            f00000 (  15.000 MB)
Free                                         ba0f000             f1000 ( 964.000 kB)
Image                                       767b3000            879000 (   8.473 MB)
TEB                                         7e898000              1000 (   4.000 kB)
Other                                       7efb0000             23000 ( 140.000 kB)
PEB                                         7efde000              1000 (   4.000 kB)


!heap -s
************************************************************************************************************************
                                              NT HEAP STATS BELOW
************************************************************************************************************************
LFH Key                   : 0x37db7eb7
Termination on corruption : ENABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                    (k)     (k)    (k)     (k) length      blocks cont. heap 
-----------------------------------------------------------------------------
Virtual block: 43a90000 - 43a90000 (size 00000000)
00770000 00000002 1411920 1402508 1411920  12100  3140   421    1    56a   LFH
00130000 00001002    1088    888   1088    170    18     2    0      0   LFH
00580000 00001002   57680  56328  57680   1723   890    38    0    202   LFH
00670000 00001002     256    256    256      9     9     1    0      0   LFH
...
-----------------------------------------------------------------------------

Output shows that virtual block 00770000 is holding 1411920 k memory.

!heap -stat -h 00770000
heap @ 00770000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    78 5e6c95 - 2c42e5d8  (57.94)
    104 8647c - 8860df0  (11.16)
    fc 80000 - 7e00000  (10.31)
    20 2a10c2 - 5421840  (6.88)
    ...

Output shows that 57.94% of blocks are of size 78.

!heap -flt s 78
shows a number of pointers that hold onto blocks of size 78


!heap -p -a <memory address>
shows the stack at memory address 


Reference: https://www.codeproject.com/Articles/31382/Memory-Leak-Detection-Using-Windbg