Re: HeapAlloc heap fragmentation.
- From: "Ivan Brugiolo [MSFT]" <Ivan.Brugiolo@xxxxxxxxxxxxxxxxxxxx>
- Date: Mon, 7 Nov 2005 23:18:36 -0800
This is contrary to evidence and implementation (see code and debugger
evidence)
What are you using to conclude that blocks are never released ?
Given the following fragment:
#define MAX_ALLOC 256
#define HEAP_GRANULARITY (2*sizeof(ULONG_PTR))
#define HEAP_ENTRY_MAX 0xFFFE
int __cdecl
wmain(int argc, WCHAR * argv[])
/*++
--*/
{
PVOID Array[MAX_ALLOC];
for (ULONG Iter = 0; Iter < MAX_ALLOC; Iter++){
Array[Iter] = HeapAlloc(GetProcessHeap(),0,HEAP_GRANULARITY *
HEAP_ENTRY_MAX) ;
}
DbgBreakPoint();
for (ULONG Iter = 0; Iter < MAX_ALLOC; Iter++){
HeapFree(GetProcessHeap(),0,Array[Iter]) ;
}
DbgBreakPoint();
return 0;
}
At the first breakpoint:
0:000> !heap -p -all
_HEAP @ c0000
_HEAP_LOOKASIDE @ c0cd0
_HEAP_SEGMENT @ c0c50
CommittedRange @ c0cc0
HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
// snip
VirtualAllocdBlocks @ c0090
2b0030: fffe : N/A [N/A] - 2b0040 (fffe0) - (busy VirtualAlloc)
// other 255 blocks similar to the previous one
At the second breakpoint
0:000> !heap -p -all
_HEAP @ c0000
_HEAP_LOOKASIDE @ c0cd0
_HEAP_SEGMENT @ c0c50
CommittedRange @ c0cc0
HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
// snip
VirtualAllocdBlocks @ c0090
// no blocks, meaning they have been free-ed
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
"Philip Borghesani" <PhilBorg@xxxxxxxxxxxxxxxx> wrote in message
news:eoMCG9%234FHA.1184@xxxxxxxxxxxxxxxxxxxxxxx
> Our application has bumped into what seems to be a limitation of the
> HeapAlloc system on Win32.
>
>
>
> It appears that if an application allocate a large portion of the
> available address space in object of size less then 0x7FFF8 bytes and then
> releases this memory there is no way to reclaim the address space for
> allocations of size greater then 7FFF8 bytes.
>
>
>
> Using the low fragmentation heap does not seem to help.
>
>
>
> Are there any known work a-rounds for this issue other then replacing
> HeapAlloc (actually standard c++ allocators in Visual C 7)?
>
>
>
> Example code:
>
>
>
> // TestHeapAlloc.cpp This program will cause a machine with less then
> 2gb ram to thrash badly
>
> // do no run with less then 1gb ram.
>
> // if this program is run on a machine with the -3gb boot switch
> (or win64) then the sizes
>
> // may need to be modified to produce a failure
>
>
>
> #include "stdafx.h"
>
> #include "windows.h"
>
>
>
> HANDLE heap=NULL;
>
>
>
> void TestLargeBlock(size_t size)
>
> {
>
> void *ptr=HeapAlloc(heap,0,size); // 500 mb
>
> if (ptr!=NULL) {
>
> printf("Allocated %Id bytes\n",HeapSize(heap,0,ptr));
>
> } else {
>
> printf("Failed to allocate %Id bytes\n",size);
>
> }
>
> HeapFree(heap,0,ptr);
>
> }
>
>
>
> size_t const MaxPointers=10000;
>
>
>
> void TestSmallBlocks(int NumPointers,size_t size)
>
> {
>
> void *pointers[MaxPointers];
>
> int count=0;
>
> memset(pointers,0,sizeof(pointers));
>
> for (int i=0; i< NumPointers; i++)
>
> {
>
> pointers[i]=HeapAlloc(heap,0,size);
>
> if (pointers[i]==NULL) {
>
> break;
>
> } else {
>
> count++;
>
> }
>
> }
>
> printf("Allocated %d items of size %Id for a total of %Iu
> bytes\n",count,size,count*size);
>
> // now free the memory
>
> for (int i=0; i< count; i++)
>
> {
>
> HeapFree(heap,0,pointers[i]);
>
> }
>
> }
>
>
>
> int _tmain(int argc, _TCHAR* argv[])
>
> {
>
> heap=GetProcessHeap(); // initialize program global heap
>
> size_t const AllocCutoff=0x7FFF8;
>
> size_t const SmallAlloc=AllocCutoff-8000;
>
> size_t const BiggerAlloc=AllocCutoff;
>
>
>
> // prove can access and free large memory blocks
>
> TestSmallBlocks(MaxPointers,BiggerAlloc);
>
> TestLargeBlock(0x20000000); // 500 mb
>
>
>
> /// Grow the heap
>
> TestSmallBlocks(MaxPointers,SmallAlloc);
>
>
>
> // check heap info
>
>
>
> size_t maxblock=HeapCompact(heap,0);
>
> printf("HeapCompact erroneously reports a large max block size of
> %Id\n",maxblock);
>
>
>
> // try to allocate a large block
>
>
>
> TestLargeBlock(maxblock/2); // can't even allocate ½ reported size
>
>
>
> // try to allocate slightly bigger small blocks this is the most
> painful example
>
> // possibly not even one allocation will happen
>
> TestSmallBlocks(MaxPointers,BiggerAlloc);
>
> }
>
>
>
>
>
>
.
- Follow-Ups:
- Re: HeapAlloc heap fragmentation.
- From: Philip Borghesani
- Re: HeapAlloc heap fragmentation.
- References:
- HeapAlloc heap fragmentation.
- From: Philip Borghesani
- HeapAlloc heap fragmentation.
- Prev by Date: Re: HeapAlloc heap fragmentation.
- Next by Date: Re: Windows Xp Unique ID
- Previous by thread: Re: HeapAlloc heap fragmentation.
- Next by thread: Re: HeapAlloc heap fragmentation.
- Index(es):
Relevant Pages
|