On Saturday, 4 March 2017 at 18:09:10 UTC, Anthony wrote:
I've been having difficulty finding an up-to-date answer to this question, so I figured I'd ask the forum: can deterministic memory management be done in D, without losing any main features?
First let's admit that C++ determinism is a strong point and that D fares a bit worse on this.
I'll give you the simplistic rules for deterministic destruction now (which is required for C++-style deterministic memory management). If you follow these rules your program destruction will be deterministic and you might even push into being exception-safe if you are so inclined. :)
- Use struct RAII wrappers and destructors to release resources. Typically structs with disabled postblit. However very often resources are classes objects because they feature virtual dispatch.
- In destructors, call .destroy on members that are class objects (reverse order of their creation if possible). Also on heap allocated struct but those are rare. The idea is that when the GC kicks in, unreachable objects on the heap should already have already been destroyed.
- Don't let the GC release resources, with the "GC-proof resource class idiom". I remember Andrei pushing for the GC not to call destructors, to no avail. So the GC is calling destructors and you should use it as a _warning that something is wrong_ and determinisim wasn't respected, not as a safety measure and a way to actually release resources (because it's wrong thread, wrong timing, unreliable).
- Like in C++, if your ownership is in the case where it's shared, you can introduce artificial owners (eg: arena pool owns arena pool items).
- The resources that are only memory need no owner and can be managed by the GC. (eg: strings, a ubyte[] array...)
When you have deterministic destruction, it's simple to offload work from GC to manual memory management. You don't loose ANY main feature.
The GC is an efficient way to call free(), and a global owner not a way to release resources.
The problem of GC efficiency itself is separate.