On Saturday, 22 June 2019 at 16:52:07 UTC, Anonymouse wrote:
I'm looking into why my thing does so many memory allocations.
Profiling with kcachegrind shows _d_allocmemory being called
upon entering a certain function, lots and lots of times.
It's a function that receives concurrency messages, so it
contains nested functions that close over local variables.
Think receiveTimeout(0.seconds, &nested1, &nested2, &nested3,
...) with 13 pointers to nested functions passed.
When entering the following function, does it allocate:
1. 0 times, because while there are closures defined, none is
ever called?
2. 2 times, because there are closures over two variables?
3. 20 times, because there are 20 unique closures?
Clearly this is a good time for you to learn about the tools D
offers to profile allocations. There is the --profile=gc DMD
argument that you can use but here there's something better:
DMD's GC has a few hooks that are directly inside druntime and
therefore available to any D program.
Putting your above code in test.d you can then do:
$ dmd test.d
$ ./test --DRT-gcopt=profile:1
Number of collections: 2
Total GC prep time: 0 milliseconds
Total mark time: 0 milliseconds
Total sweep time: 0 milliseconds
Max Pause Time: 0 milliseconds
Grand total GC time: 0 milliseconds
GC summary: 1 MB, 2 GC 0 ms, Pauses 0 ms < 0 ms
And here is your answer: two allocations. More information about
--DRT-gcopt there: https://dlang.org/spec/garbage.html