! heap -stat -h does not display distribution

I am trying to determine why my applications consume 4 GB of private bytes. So I took a complete memory dump, loaded it into windbg. But when analyzed using !heap -stat -hstrange results that do not add up:

0:000> !heap -s
(...)
          Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                            (k)     (k)    (k)     (k) length      blocks cont. heap 
-------------------------------------------------------------------------------------
000002d0a0000000 00000002 2800804 2780508 2800700   2984  1980   177    0      6   LFH
000002d09fe10000 00008000      64      4     64      2     1     1    0      0      
000002d09ff70000 00001002 1342924 1334876 1342820  13042  3342    87    0      0   LFH

Ok, I have a bunch of 2.8GB and a bunch of 1.34GB. Let's look at the selection of the first:

0:000> !heap -stat -h 000002d0a0000000 
 heap @ 000002d0a0000000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    651 291 - 1035e1  (16.00)
    79c 1df - e3ce4  (14.06)
    28 156d - 35908  (3.31)
    (...)

IIUC, the first line indicates the block size 0x651 (= 1617 bytes), numeric blocks 0x291 (= 657), for general bytes 0x103531 (= 1062369 bytes = ~ 1 MB) and 16% of the total number of occupied bytes. But, looking at the summary, there should be ~ 2.8 GB of occupied bytes!

Other mismatch:

0:000> !heap -stat -h 000002d0a0000000 -grp A
 heap @ 000002d0a0000000
group-by: ALLOCATIONSIZE max-display: 20
    size     #blocks    total     ( %) (percent of total busy bytes)
    a160 1 - a160  (0.62)
    7e50 2 - fca0  (0.97)

0:000> !heap -h 000002d0a0000000
(...)
(509 lines that note allocations with size 7e50, like this one:)
    000002d0a3f48000: 11560 . 07e60 [101] - busy (7e50)

Edit: many lines also say Internalat the end, which meansHEAP_ENTRY_VIRTUAL_ALLOC - but 509 lines (7e50)do not.

: !heap -stat -h, , !heap -s?

+4
1

, . .

- , VirtualAlloc(). ++ . ( ) ( ). !heap -s .

, , , ++, . ++. , malloc()/free() new/delete.

, . ++ ,

  • , 64k
  • ( , , , )

, .

, :

  • 2,8 .
  • 000002d0a0000000 ~ 1 /16% = 6,25 , (, , )

++:

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <string>
#include <iomanip>

int main()
{
    HANDLE hHeap = HeapCreate(0, 0x1000000, 0x10000000); // no options, initial 16M, max 256M
    HeapAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS, 511000); // max. allocation size for non-growing heap
    std::cout << "Debug now, handle is 0x" << std::hex << std::setfill('0') << std::setw(sizeof(HANDLE)) << hHeap << std::endl;
    std::string dummy;
    std::getline(std::cin, dummy);
    return 0;
}

511kB 100%, ~ 1/32 16 :

0:001> !heap -stat -h 009c0000
 heap @ 009c0000
group-by: TOTSIZE max-display: 20
    size     #blocks     total     ( %) (percent of total busy bytes)
    7cc18 1 - 7cc18  (100.00)

, !heap -h <heap> -f:

0:001> !heap -h 0x01430000 -f
Index   Address  Name      Debugging options enabled
  3:   01430000 
    Segment at 01430000 to 11430000 (01000000 bytes committed)
    Flags:                00001000
    ForceFlags:           00000000
    Granularity:          8 bytes
    Segment Reserve:      00100000
    Segment Commit:       00002000
    DeCommit Block Thres: 00000200
    DeCommit Total Thres: 00002000
    Total Free Size:      001f05c7
    Max. Allocation Size: 7ffdefff
    Lock Variable at:     01430138
    Next TagIndex:        0000
    Maximum TagIndex:     0000
    Tag Entries:          00000000
    PsuedoTag Entries:    00000000
    Virtual Alloc List:   014300a0
    Uncommitted ranges:   01430090
    FreeList[ 00 ] at 014300c4: 01430590 . 0240e1b0  
        0240e1a8: 7cc20 . 21e38 [100] - free             <-- no. 1
        02312588: 7f000 . 7f000 [100] - free             <-- no. 2
        [...]
        01430588: 00588 . 7f000 [100] - free             <-- no. 32

    Heap entries for Segment00 in Heap 01430000
         address: psize . size  flags   state (requested size)
        01430000: 00000 . 00588 [101] - busy (587)
        01430588: 00588 . 7f000 [100]
        [...]
        02312588: 7f000 . 7f000 [100]
        02391588: 7f000 . 7cc20 [101] - busy (7cc18)
        0240e1a8: 7cc20 . 21e38 [100]
        0242ffe0: 21e38 . 00020 [111] - busy (1d)
        02430000:      0f000000      - uncommitted bytes.
0:001> ? 7cc18
Evaluate expression: 511000 = 0007cc18

, 256 (240 , 0x0f000000 + 16 , 0x01000000). FreeList,

0:001> ? 0n31 * 7f000 + 21e38 
Evaluate expression: 16264760 = 00f82e38

, (~ 16 ) ++. 16 ​​ !heap -s WinDbg 6.2.9200:

0:001> !heap -s
LFH Key                   : 0x23e41d0e
Termination on corruption : ENABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                    (k)     (k)    (k)     (k) length      blocks cont. heap 
-----------------------------------------------------------------------------
004d0000 00000002    1024    212   1024      6     5     1    0      0   LFH
00750000 00001002      64     20     64      9     2     1    0      0      
01430000 00001000  262144  16384 262144  15883    32     1    0      0      
    External fragmentation  96 % (32 free blocks)
-----------------------------------------------------------------------------

: 262144k - 16384 commit = 245760k .

, , .

. : , , .

, , 512 (32 ) 1 (64 ), MSDN . .

, - 0.

, ,

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <string>
#include <iomanip>

int main()
{
    HANDLE hHeap = HeapCreate(0, 0x1000000, 0); // no options, initial 16M, growable
    HeapAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS, 20*1024*1024); // 20 MB, force growing
    std::cout << "Debug now, handle is 0x" << std::hex << std::setfill('0') << std::setw(sizeof(HANDLE)) << hHeap << std::endl;
    std::string dummy;
    std::getline(std::cin, dummy);
    return 0;
}

!heap :

0:001> !heap -s
LFH Key                   : 0x7140028b
Termination on corruption : ENABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                    (k)     (k)    (k)     (k) length      blocks cont. heap 
-----------------------------------------------------------------------------
006d0000 00000002    1024    212   1024      6     5     1    0      0   LFH
001d0000 00001002      64     20     64      9     2     1    0      0      
Virtual block: 01810000 - 01810000 (size 00000000)
00810000 00001002   16384  16384  16384  16382    33     1    1      0      
    External fragmentation  99 % (33 free blocks)
-----------------------------------------------------------------------------

, , 0. , , "" WinDbg. , 6.2.9200, , .

+2

Source: https://habr.com/ru/post/1616076/


All Articles