Bug 13801 – Garbage collector fails to work after lots of small allocations

Status
RESOLVED
Resolution
WORKSFORME
Severity
critical
Priority
P2
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
Mac OS X
Creation time
2014-11-30T21:42:17Z
Last change time
2023-06-22T13:01:41Z
Assigned to
No Owner
Creator
Ben Grabham

Comments

Comment #0 by dlang — 2014-11-30T21:42:17Z
The program below uses around 3.5GB of RAM on my machine. - Commenting out the "arr" allocation reduces it to 860KB. - Commenting out the list appending reduces it to 8.8MB. This is seriously affecting me as my program is now allocating over 10GB before OOM'ing. Things to note: - Reduce the size multiplier to only 1000 and the amount of memory being used drops to hardly anything. - Increase the multiplier to 3000 and the amount of memory being used drastically increases. ------------------------------------------- import core.memory : GC; import std.range : iota; const ulong size = chunkSize * 2000; const ulong chunkSize = 4 * 1024 * 1024; immutable struct S { string a; ulong b; } void main() { S[] list; foreach(i; iota(0, size, chunkSize)) { list ~= S("", i); } while(true) { ubyte[] arr = new ubyte[chunkSize]; //GC.collect(); //GC.minimize(); } }
Comment #1 by dlang — 2014-11-30T21:43:06Z
Also, adding GC.collect() and GC.minimize() explicitly did nothing as well.
Comment #2 by dlang — 2014-11-30T21:54:20Z
If you take out iota as well, it works again. If you add a sleep into the while, the memory increases more gradually.
Comment #3 by schuetzm — 2014-12-07T14:10:40Z
FWIW, I can't reproduce it on x86_64 Linux with DMD master. I've even raised the multiplier up to 128000, and RES stayed at a modest 19MB.
Comment #4 by dlang — 2014-12-07T14:52:18Z
The initial test was on: DMD64 D Compiler v2.066.1 I just tested it on (dmd master): DMD v2.067-devel-8ff302a DEBUG It takes up insane amounts of memory on both. (only tested on mac)
Comment #5 by r.sagitario — 2014-12-07T16:48:47Z
AFAIK the heap on OSX starts 0x 0x1_0000_0000, so your "b" members create false pointers into the memory chunks into the arrays allocated in the while(true) loop. That's why they are never collected. You might want to try one of the proposed precise GCs: https://github.com/D-Programming-Language/druntime/pull/1022 or https://github.com/D-Programming-Language/druntime/pull/1057