GC behavior

Gregor Mückl gregormueckl at gmx.de
Fri Jun 7 14:33:59 UTC 2019


On Friday, 7 June 2019 at 12:28:50 UTC, Gregor Mückl wrote:
> Hi!
>
> I'm not 100% sure if I'm in the right here, but I believe that 
> the following program shouldn't have unbounded heap growth to 
> the point where it runs out of memory:
>
> module gctest;
>
> import core.memory;
> import core.thread;
>
> void main()
> {
>     for(int i = 0; i < 10000; i++) {
>         int[] x = new int[10000000];
>         Thread.sleep(dur!"msecs"(200));
>         //GC.collect(); // keeps program from failing
>     }
> }
>
> If GC.collect() is called constantly, heap size stays pretty 
> much constant. Tested only on Windows 10 (64 bit) with DMD 
> 2.086.0 so far. I'd say that this behavior is a bug.

It's a bit stranger than that: the following program doesn't fail 
only because it has the writeln with the string concatenation in 
it. I discovered it by accident while trying to look into how 
Windows reports available memory to 32 bit programs.

module gctest;

import core.thread;
import std.conv;
import std.stdio;

void main()
{
     for(int i = 0; i < 10000; i++) {
         int[] x = new int[10000000];
         Thread.sleep(dur!"msecs"(200));
         writeln("allocation " ~ to!string(i));
     }
}

Just the writeln without any concatenation will still not trigger 
garbage collection runs. What is it about the ~ operator 
implementation that changes the behavior so drastically?

As a side note, I don't think that GlobalMemoryStatus on Windows 
works the way the GC code thinks it's working. It will always 
happily report 2^31 bytes total and available memory, no matter 
how big the heap of the 32 bit program is. So isLowOnMem in 
gc/os.d should actually be broken in this particular situation.


More information about the Digitalmars-d mailing list