Hi,
I have an app that loads some data; 1 out of 10 times memory
allocation fails at some point, even though it looks like there is
enough free memory to complete the operation according to windbg:
0:041> !address -summary
<...>
1f0b0000 ( 508608) : 24.25% : MEM_FREE
<...>
Largest free region: Base 58e61000 - Size 01f0f000 (31804 KB)
(and the operation just needs 4064776 bytes)
Is there a way to find out what exactly go wrong?
A related question, do I have to know what interface is used for
allocation to tell why it failed?... cuz right know I don't, but I
guess it goes thru VMM anyways? If I need to know, how do I find out?
The code is something along this lines (this is CoreFoundation on
Win32):
static void __CFDictionaryGrow(CFMutableDictionaryRef dict, CFIndex
numNewValues) {
<...>
dict->_keys = CFAllocatorAllocate(CFGetAllocator(dict), 2 * dict-
>_bucketsNum * sizeof(const void *), 0);
if (NULL == dict->_keys) __CFAbort();
<...>
}
void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size,
CFOptionFlags hint) {
CFAllocatorAllocateCallBack allocateFunc;
allocator = (NULL == allocator) ? __CFGetDefaultAllocator() :
allocator;
allocateFunc = __CFAllocatorGetAllocateFunction(&allocator-
>_context);
newptr = (void *)INVOKE_CALLBACK3(allocateFunc, size, hint,
allocator->_context.info);
return newptr;
}
My app quits at __CFAbort(), so the allocator returned null... but I
couldn't figure out what function is used.
|
The availability of large contiguous free area in the address space
of the process does not imply or guarantee that the allocator
is able/capable of using it.
For eaxmple, if you are in an OS before Vista, the ntdll heap has a limit
of 64 segments. If all segments are used and they are heavily
internally fragmented, then they are not able to satisfy your allocation,
and, if the allocation is so small that it does not go to the Virtual-Alloc
block list, then, it simply will not be satisfied.
Assuming your allocator is the Ntdll.dll heap manager, then,
you can use `!heap -p -h <handle>` and inspect the blocks
labelled as `(free)` of `(free )`, to see if any block exist that would
satisfy your request.
That said, it is known that the doubl-up growing strategy for vectors,
arrays and/or hash-tables is extremely likely to created
a huge internal fragmentation. Again, inspection of `!heap -p -h`
should give you some clues.
--
--
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
<lorentdick@yahoo.com> wrote in message
news:b9e47031-7026-4bd7-aa9c-540494f2ee22@m36g2000hse.googlegroups.com...
> Hi,
>
> I have an app that loads some data; 1 out of 10 times memory
> allocation fails at some point, even though it looks like there is
> enough free memory to complete the operation according to windbg:
>
> 0:041> !address -summary
> <...>
> 1f0b0000 ( 508608) : 24.25% : MEM_FREE
> <...>
> Largest free region: Base 58e61000 - Size 01f0f000 (31804 KB)
>
> (and the operation just needs 4064776 bytes)
>
> Is there a way to find out what exactly go wrong?
>
>
>
> A related question, do I have to know what interface is used for
> allocation to tell why it failed?... cuz right know I don't, but I
> guess it goes thru VMM anyways? If I need to know, how do I find out?
> The code is something along this lines (this is CoreFoundation on
> Win32):
>
> static void __CFDictionaryGrow(CFMutableDictionaryRef dict, CFIndex
> numNewValues) {
> <...>
> dict->_keys = CFAllocatorAllocate(CFGetAllocator(dict), 2 * dict-
>>_bucketsNum * sizeof(const void *), 0);
> if (NULL == dict->_keys) __CFAbort();
> <...>
> }
>
> void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size,
> CFOptionFlags hint) {
> CFAllocatorAllocateCallBack allocateFunc;
> allocator = (NULL == allocator) ? __CFGetDefaultAllocator() :
> allocator;
> allocateFunc = __CFAllocatorGetAllocateFunction(&allocator-
>>_context);
> newptr = (void *)INVOKE_CALLBACK3(allocateFunc, size, hint,
> allocator->_context.info);
> return newptr;
> }
>
>
> My app quits at __CFAbort(), so the allocator returned null... but I
> couldn't figure out what function is used.
>
> Any suggestions please?
|