std.container and classes

Jonathan M Davis jmdavisProg at gmx.com
Tue Dec 20 21:07:23 PST 2011


On Monday, December 19, 2011 08:54:00 Jacob Carlborg wrote:
> The Tango runtime has added a new method in Object, "dispose". This
> method is called when "scope" is used or "delete" is explicitly called.
> I don't know if that would help.

That sounds a lot like using clear, though clear doesn't free memory unless 
the finalizer does (and I'm not sure that managing memory with finalizers 
actually works right now; there were issues with that previously - but it 
might have only been GC memory, so perhaps malloc and free would still work). 
The issue with them is escaping references. You can easily end up with 
references to data which has been destroyed. It also makes them harder to pass 
around unless you essentially wrap the container in ref-counted struct.

The lifetime of the container must be managed if you really want to be able to 
use custom allocators or have the container be as efficient as possible with 
regards to its memory usage in the general case. With a struct, it manages 
itself. It can do whatever it wants to with memory internally, and the 
combination of its constructor, postblit constructor, and destructor allows it 
to take care of it itself and clean up its memory when it's destroyed. You 
also don't have issues of stuff referring to a container which doesn't exist 
anymore (unless you add pointers to the container into the mix and then move 
or destroy the container).

With classes, if they're owned by the GC, then it's the GC that manages their 
lifetime. It destroys them when they're no longer referenced and it runs a 
collection cycle. You have no control over its lifetime, and even if it tries 
to manage its memory internally on some level, that memory won't be cleaned up 
until the GC collects the container itself. So, if you want to manage the 
lifetime of the class, you can't use a naked reference anymore. You need a way 
to get the GC to collect it, or you need to have it somewhere else other than 
the GC heap.

If you use something like Scoped, then its lifetime will be tied to the scope 
that it's in, but you risk references to it escaping, and limiting the 
container to a particular scope could be far too limiting anyway. That being 
the case, if you want to use an allocator other than the GC for the class 
itself, then you're probably going to have to stick it in a struct. That 
struct could then manage the container's lifetime on some level. It would 
probably have to use ref-counting and then call clear on the container when 
the ref-count hits zero. That should then allow the container to at least 
clean up its internal memory, assuming that that's not on the GC heap, but 
unless you use emplace on non-GC heap memory, the container itself still can't 
be collected until the GC collects it (since clear destroys it but doesn't 
free its memory). Not to mention, if you're using a ref-counted struct to hold 
a class in order to manage that class' lifetime, why on earth did you make it 
a class in the first place?

If what you're suggesting with dispose is that it would act like clear except 
that it would actually free the container, well that pretty much goes against 
the direction that we've been trying to go with the GC, which is to not have 
the programmer explicitly freeing anything on the GC heap (which is why delete 
is being removed from the language).

I really think that if we want deterministic destruction of containers, they 
need to be structs. And if we want to use custom allocators with containers, I 
don't see how we could reasonably expect them to be of much use unless we're 
expecting that programmers will explicitly call clear on them when they're 
done with them. So, while the fact that containers need to be reference types 
does imply that classes are the way to go, I think that we're going to have to 
go with structs if we want their memory management to be more efficient than 
simply letting the GC handle it.

- Jonathan M Davis


More information about the Digitalmars-d mailing list