I would assume that has to do with the counter-speedoptimal behavior of the GC which try to minimize the RAM usage instead the same way as "professional" GCs (C#, JAVA, Eiffel) work. (they do not minimize the usage ... there is no real reason for it, if there is free RAM anyway)
Found a similar behavior (but much worse on freeing - thought it was broken as it hadn't freed 5 mins later) when trying to find something that lets the GC fail. But that was influenced by strings in the list and this strings length as well. (you can do a simple while loop and add a string to a list until a given memory alloced border is reached. When doing with string = string + string it will need forever to clean, with string = string + "a" it will take quite long on first run as well but not nearly as worse as with the first version)
Found a similar behavior (but much worse on freeing - thought it was broken as it hadn't freed 5 mins later) when trying to find something that lets the GC fail. But that was influenced by strings in the list and this strings length as well. (you can do a simple while loop and add a string to a list until a given memory alloced border is reached. When doing with string = string + string it will need forever to clean, with string = string + "a" it will take quite long on first run as well but not nearly as worse as with the first version)