On Wednesday, 8 May 2013 at 12:03:08 UTC, Steven Schveighoffer
wrote:
On Wed, 08 May 2013 06:20:45 -0400, Matic Kukovec
<matic.kuko...@pametnidom.si> wrote:
Was playing around with the code and found that this WORKS:
(note the "app_temp_array.reserve(50000000);" at the top,
without this line it doesn't work)
[snip]
The memory usage shrinks from 400MB to 2MB, which is right!
Why?
This is the conservative garbage collector at work.
What happens is there is a "false pointer", or a word-aligned
32-bit value on the stack, or in global registers, that points
at one of the arrays that you allocate.
As you append, and the GC needs to allocate larger and larger
arrays to hold your new data, the old ones are left behind for
the GC to collect. But some random integer somewhere happens
to "point" at one of those arrays. It is then kept in memory.
It doesn't have to be a large array. GC.minimize can only
shrink the OS-provided memory block, which is sequential. If
any data is still valid, even if there is a bunch of free pages
below that data, it cannot be returned to the OS.
When you reserve, however, one, and only one, memory block is
allocated. This block you are explictly freeing at the end, so
it will be collected. Then minimize can do a good job.
Not saying you should do things this way, just explaining the
behavior. arr.reserve is a good tool to use when you know how
much data you will need. But it can't fix every situation.
-Steve
Thanks for the explanation Steve.
Can you please give me a correct example of:
- creating a dynamic string array
- looping over it and adding values
- discarding/releasing the array from memory
Thanks, Matic