Best memory management D idioms
XavierAP via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Mar 5 12:54:06 PST 2017
I was going to name this thread "SEX!!" but then I thought "best
memory management" would get me more reads ;) Anyway now that I
have your attention...
What I want to learn (not debate) is the currently available
types, idioms etc. whenever one wants deterministic memory
management. Please do not derail it debating how often
deterministic should be preferred to GC or not. Just, whenever
one should happen to require it, what are the available means?
And how do they compare in your daily use, if any? If you want to
post your code samples using special types for manual memory
management, that would be great.
AFAIK (from here on please correct me wherever I'm wrong) the
original D design was, if you don't want to use GC, then malloc()
and free() are available from std.c. Pretty solid. I guess the
downside is less nice syntax than new/delete, and having to check
the returned value instead of exceptions. I guess these were the
original reasons why C++ introduced new/delete but I've never
been sure.
Then from this nice summary [1] I've learned about the existence
of new libraries and Phobos modules: std.typecons, Dlib, and
std.experimental.allocator. Sadly in this department D starts to
look a bit like C++ in that there are too many possible ways to
do one certain thing, and what's worse none of them is the
"standard" way, and none of them is deprecated atm either. I've
just taken a quick look at them, and I was wondering how many
people prefer either, and what are their reasons and their
experience.
dlib.core.memory and dlib.memory lack documentation, but
according to this wiki page [2] I found, dlib defines New/Delete
substitutes without GC a-la-C++, with the nice addition of a
"memoryDebug" version (how ironclad is this to debug every memory
leak?)
From std.typecons what caught my eye first is scoped() and
Unique. std.experimental.allocator sounded quite, well,
experimental or advanced, so I stopped reading before trying to
wrap my head around all of it. Should I take another look?
scoped() seems to work nicely for auto variables, and if I
understood it right, not only it provides deterministic
management, but allocates statically/in the stack, so it is like
C++ without pointers right? Looking into the implementation, I
just hope most of that horribly unsafe casting can be taken care
of at compile time. The whole thing looks a bit obscure under the
hood and in its usage: auto is mandatory or else allocation
doesn't hold, but even reflection cannot tell the different at
runtime between T and typeof(scoped!T) //eew. Unfortunately this
also makes scoped() extremely unwieldy for member variables:
their type has to be explicitly declared as typeof(scoped!T), and
they cannot be initialized at the declaration. To me this looks
like scoped() could be useful in some cases but it looks hardly
recommendable to the same extent as the analogous C++ idiom.
Then Unique seems to be analogous to C++ unique_ptr, fair
enough... Or are there significant differences? Your experience?
And am I right in assuming that scoped() and Unique (and
dlib.core.memory) prevent the GC from monitoring the memory they
manage (just like malloc?), thus also saving those few cycles?
This I haven't seen clearly stated in the documentation.
[1]
http://forum.dlang.org/post/stohzfatiwjzemqojeol@forum.dlang.org
[2]
https://github.com/gecko0307/dlib/wiki/Manual-Memory-Management
More information about the Digitalmars-d-learn
mailing list