OutOfMemory even if there is free memory

Hello,

Maybe I miss something obvious but it seens like I get an OutOfMemoryException even if I have free memory left.

I do a Debug.GC(true) followed by a File.ReadAllBytes and I get the exception with the following output.


GC: 2msec 35028 bytes used, 19104 bytes available
Type 0F (STRING              ):    660 bytes
Type 11 (CLASS               ):   3456 bytes
Type 12 (VALUETYPE           ):    180 bytes
Type 13 (SZARRAY             ):   3384 bytes
Type 15 (FREEBLOCK           ):  19104 bytes
Type 17 (ASSEMBLY            ):  18072 bytes
Type 18 (WEAKCLASS           ):     48 bytes
Type 19 (REFLECTION          ):     84 bytes
Type 1B (DELEGATE_HEAD       ):    252 bytes
Type 1D (OBJECT_TO_EVENT     ):    120 bytes
Type 1E (BINARY_BLOB_HEAD    ):   2508 bytes
Type 1F (THREAD              ):   1152 bytes
Type 20 (SUBTHREAD           ):    144 bytes
Type 21 (STACK_FRAME         ):   2880 bytes
Type 27 (FINALIZER_HEAD      ):    144 bytes
Type 31 (IO_PORT             ):    180 bytes
Type 34 (APPDOMAIN_HEAD      ):     72 bytes
Type 36 (APPDOMAIN_ASSEMBLY  ):   1692 bytes
Failed allocation for 755 blocks, 9060 bytes

Why can’t I allocate 9 060 bytes when I have 19 104 bytes available ? Any Clue ?

The VS debugger does some really strange things to available memory. Try doing the same without the debugger running. You could trap the exception and blink a LED and/or write free memory number to an LCD or other display.

I’ve never investigated the details, but have had this exception thrown while debugging. Deployed the same code and the exception magically vanished.

This helpful nugget of information was passed along from another forum member, who has really pushed the envelope of displaying graphic files on the small FEZes. Thanks @ skewworks for going “where no one has gone before”.

I’ve had this happen with 19kb free and only asking for 6k. It needs a block of memory with no “holes” in it to allocate.

Try and do the operation early in the program before other things have fragmented the memory.

Ok thanks, I’ll try the Debug/release thing and allocating my buffer earlier in the program.

For the fragmented memory I was afraid of something like this. I guess there is no way to ask the CLR to defragment my ram xD.

Yes there is a way Debug.GC(true);

@ Gus Is Debug.GC(true) considered a “production” command or only meant for debugging? I’m always worried about using it in release code because it is so unpredictable. I’d rather want to rely on a Dispose but it still doesn’t seem to guarantee free usable memory.

I must say it is fun living on the edge (of memory) but it hurts when you fall off :slight_smile:

I think it is important to have and use in production

I would say every effort should be made not to have to use it in production. :stuck_out_tongue:

In embedded systems, dynamic memory allocation can lead to problems. Every effort should be made to allocate large blocks during initialization.

BTW, dispose frees an object, but the object memory is not available immediately. The actual recovery of the associated memory doesn’t happen until GC occurs, which happens automatically or manually.

I disagree and in some cases using this is a must.

This is fixed in NETMF4.2 where out of memory automatically causes a heap compaction, so this is no longer needed.