Free memory can be found in two forms:
- The free space between the heap and the stack. This is usually the main chunk of free memory.
- Heap "holes", i.e. pieces of unallocated memory within the heap. The presence of these holes is called "heap fragmentation".
There are various versions of the MemoryFree library. The simplest ones only report the main chunk between the heap and the stack. The more sophisticated ones walk the malloc()'s free list in order to also count the heap holes. Which approach is better? I would argue that the naive version is fine, as heap holes is something you should not count on, because it is never guaranteed that a particular allocation will fit in any of those holes.
You are visibly using one of the naive versions. As you grow your
string, the object calls realloc()
, which in some cases copies the
string's character array and frees the original one, potentially
creating a heap hole. Eventually, small holes can coalesce into a larger
onesmall holes can coalesce into a
larger one big enough for the next allocation, andrealloc()
can end up using
this this large hole and freeing the chunk at the
the top of the heap. When this
happens happens, the heap shrinks, and the main chunk
chunk of free memory gets
larger larger, which is what freeMemory()
is reporting
reporting to you.
In summary, it's normal and expected behavior. If you want something less surprising, use a version of the library that does count the holes. But then you may run into a more displeasing surprise: a heap–stack collision, or an out-of-memory condition, can happen even with loads of memory buried inside heap holes.
Free memory can be found in two forms:
- The free space between the heap and the stack. This is usually the main chunk of free memory.
- Heap "holes", i.e. pieces of unallocated memory within the heap. The presence of these holes is called "heap fragmentation".
There are various versions of the MemoryFree library. The simplest ones only report the main chunk between the heap and the stack. The more sophisticated ones walk the malloc()'s free list in order to also count the heap holes. Which approach is better? I would argue that the naive version is fine, as heap holes is something you should not count on, because it is never guaranteed that a particular allocation will fit in any of those holes.
You are visibly using one of the naive versions. As you grow your
string, the object calls realloc()
, which in some cases copies the
string's character array and frees the original one, potentially
creating a heap hole. Eventually, small holes can coalesce into a larger
one big enough for the next allocation, andrealloc()
can end up using
this large hole and freeing the chunk at the top of the heap. When this
happens, the heap shrinks, and the main chunk of free memory gets
larger, which is what freeMemory()
is reporting to you.
In summary, it's normal and expected behavior. If you want something less surprising, use a version of the library that does count the holes. But then you may run into a more displeasing surprise: a heap–stack collision, or an out-of-memory condition, can happen even with loads of memory buried inside heap holes.
Free memory can be found in two forms:
- The free space between the heap and the stack. This is usually the main chunk of free memory.
- Heap "holes", i.e. pieces of unallocated memory within the heap. The presence of these holes is called "heap fragmentation".
There are various versions of the MemoryFree library. The simplest ones only report the main chunk between the heap and the stack. The more sophisticated ones walk the malloc()'s free list in order to also count the heap holes. Which approach is better? I would argue that the naive version is fine, as heap holes is something you should not count on, because it is never guaranteed that a particular allocation will fit in any of those holes.
You are visibly using one of the naive versions. As you grow your
string, the object calls realloc()
, which in some cases copies the
string's character array and frees the original one, potentially
creating a heap hole. Eventually, small holes can coalesce into a
larger one big enough for the next allocation, andrealloc()
can end up using this large hole and freeing the chunk at
the top of the heap. When this happens, the heap shrinks, and the main
chunk of free memory gets larger, which is what freeMemory()
is
reporting to you.
In summary, it's normal and expected behavior. If you want something less surprising, use a version of the library that does count the holes. But then you may run into a more displeasing surprise: a heap–stack collision, or an out-of-memory condition, can happen even with loads of memory buried inside heap holes.
Free memory can be found in two forms:
- The free space between the heap and the stack. This is usually the main chunk of free memory.
- Heap "holes", i.e. pieces of unallocated memory within the heap. The presence of these holes is called "heap fragmentation".
There are various versions of the MemoryFree library. The simplest ones only report the main chunk between the heap and the stack. The more sophisticated ones walk the malloc()'s free list in order to also count the heap holes. Which approach is better? I would argue that the naive version is fine, as heap holes is something you should not count on, because it is never guaranteed that a particular allocation will fit in any of those holes.
You are visibly using one of the naive versions. As you grow your
string, the object calls realloc()
, which in some cases copies the
string's character array and frees the original one, potentially
creating a heap hole. Eventually, small holes can coalesce into a larger
one big enough for the next allocation, and realloc()
can end up using
this large hole and freeing the chunk at the top of the heap. When this
happens, the heap shrinks, and the main chunk of free memory gets
larger, which is what freeMemory()
is reporting to you.
In summary, it's normal and expected behavior. If you want something less surprising, use a version of the library that does count the holes. But then you may run into a more displeasing surprise: a heap–stack collision, or an out-of-memory condition, can happen even with loads of memory buried inside heap holes.