Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Následující příklad získá seznam hald pro aktuální proces. Pořídí snímek hald pomocí funkce CreateToolhelp32Snapshot a poté prochází seznamem pomocí funkcí Heap32ListFirst a Heap32ListNext. Pro každou haldu používá funkce Heap32First a Heap32Next k procházení bloků haldy.
Poznámka
Heap32First a Heap32Next jsou neefektivní, zejména pro velké haldy. Jsou ale užitečné pro dotazování na jiné procesy, ve kterých byste obvykle museli vložit vlákno do druhého procesu, aby se shromáždily informace (tato rozhraní API to dělají za vás).
Podívejte se na druhý příklad ekvivalentní, mnohem efektivnější alternativy, která používá HeapWalk místo Heap32First a Heap32Next. Všimněte si, že HeapWalk lze použít pouze pro stejný proces.
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
int main( void )
{
HEAPLIST32 hl;
HANDLE hHeapSnap = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, GetCurrentProcessId());
hl.dwSize = sizeof(HEAPLIST32);
if ( hHeapSnap == INVALID_HANDLE_VALUE )
{
printf ("CreateToolhelp32Snapshot failed (%d)\n", GetLastError());
return 1;
}
if( Heap32ListFirst( hHeapSnap, &hl ) )
{
do
{
HEAPENTRY32 he;
ZeroMemory(&he, sizeof(HEAPENTRY32));
he.dwSize = sizeof(HEAPENTRY32);
if( Heap32First( &he, GetCurrentProcessId(), hl.th32HeapID ) )
{
printf( "\nHeap ID: %d\n", hl.th32HeapID );
do
{
printf( "Block size: %d\n", he.dwBlockSize );
he.dwSize = sizeof(HEAPENTRY32);
} while( Heap32Next(&he) );
}
hl.dwSize = sizeof(HEAPLIST32);
} while (Heap32ListNext( hHeapSnap, &hl ));
}
else printf ("Cannot list first heap (%d)\n", GetLastError());
CloseHandle(hHeapSnap);
return 0;
}
Následující fragment kódu používá funkci HeapWalk k procházení hald procesu, která vytváří stejný výstup jako v předchozím příkladu, ale mnohem efektivněji:
#include <windows.h>
#include <stdio.h>
int main( void )
{
DWORD heapIndex;
DWORD heapCount = 0;
PHANDLE heaps = NULL;
while (TRUE)
{
DWORD actualHeapCount = GetProcessHeaps(heapCount, heaps);
if (actualHeapCount <= heapCount)
{
break;
}
heapCount = actualHeapCount;
free(heaps);
heaps = (HANDLE*)malloc(heapCount * sizeof(HANDLE));
if (heaps == NULL)
{
printf("Unable to allocate memory for list of heaps\n");
return 1;
}
}
for (heapIndex = 0; heapIndex < heapCount; heapIndex++)
{
PROCESS_HEAP_ENTRY entry;
printf("Heap ID: %d\n", (DWORD)(ULONG_PTR)heaps[heapIndex]);
entry.lpData = NULL;
while (HeapWalk(heaps[heapIndex], &entry))
{
// Heap32First and Heap32Next ignore entries
// with the PROCESS_HEAP_REGION flag
if (!(entry.wFlags & PROCESS_HEAP_REGION))
{
printf("Block size: %d\n", entry.cbData + entry.cbOverhead);
}
}
}
free(heaps);
return 0;
}
Procházení haldy pomocí funkce HeapWalk je zhruba lineární ve vztahu k velikosti haldy, zatímco procházení haldy pomocí funkce Heap32Next je zhruba kvadratické ve vztahu k velikosti haldy. Dokonce i pro skromnou haldu s 10 000 přiděleními běží HeapWalk 10 000krát rychleji než Heap32Next a poskytuje podrobnější informace. Rozdíl v výkonu se stává ještě dramatičtější, protože se zvyšuje velikost haldy.
Podrobnější příklad chůze haldy s HeapWalk funkce, viz Výčet haldy.