On Thursday, 27 April 2017 at 19:36:44 UTC, Ben wrote:
Frankly seeing in this example that the GC was in theory able
to kick in 6 times in a simple 100 item loop, that is not
efficient. I if did my own memory management, the variable
cleanup will have been done in one go, right after the loop.
Simply more efficient.
You can easily disable automatic collections and trigger one
manually:
----
import core.memory: GC;
GC.disable(); /* disable automatic collections */
/* ... do your loop ... */
GC.collect(); /* manually trigger collection */
GC.enable(); /* enable automatic collections */
----
Been thinking about this topic. Dlang has a destructor, does
that means if you allocate on the GC and then do your own
destructor, it technically counts as manual memory management?
I'm not sure what role the destructor supposedly plays here. A
destructor is called automatically when the object is freed, or
you can call it manually with `object.destroy` [1]. Freeing
happens when the object is collected, or you can use
`core.memory.GC.free` [2] to free without collecting. Collecting
happens automatically, or you can trigger it with
`core.memory.GC.collect` [3] as shown.
You can use a destructor to manage memory owned by the object.
But the destructor being there doesn't affect how the object
itself is managed.
That is assuming the GC removes the memory reference when you
call it. I remember seeing in some other languages ( C#
possibly? ) that referring a variable to be freed only meant
the GC freed the memory when it felt like it, not the exact
spot when you told it.
Destroying does not imply freeing. It's the other way around. If
you want to free, call `GC.free`. That does count as manual
memory management.
I personally think that people simple have a bad taste with GC
because they kick in too much outside there control. For 90%
the default behavior is good but its those 10% that leaves a
bad taste with people ( GC on critical moments and hurting
performance in return ).
You can:
1) Call `core.memory.GC.disable` [4] if you don't want the GC to
collect for a while. You should make sure that you don't run out
of memory during that time, of course. Use
`core.memory.GC.enable` [5] to enable collections again.
2) Use the `@nogc` [6] attribute to forbid GC allocations in a
function. GC collections are only triggered by allocations (or
manually). So the GC won't kick in during execution of @nogc code.
[1] https://dlang.org/phobos/object.html#.destroy
[2] https://dlang.org/phobos/core_memory.html#.GC.free
[3] https://dlang.org/phobos/core_memory.html#.GC.collect
[4] https://dlang.org/phobos/core_memory.html#.GC.disable
[5] https://dlang.org/phobos/core_memory.html#.GC.enable
[6] https://dlang.org/spec/attribute.html#nogc