On 2011-12-21 06:07, Jonathan M Davis wrote:
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.

With "dispose" it would give you the option to control the lifetime of the object, in some cases.

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 thought that one of the problems with the GC and memory was that you can't rely on when/if the destructors are called. With "dispose" it would give the developer a reliable method to cleanup resources, assuming "scope" or "delete" is used.

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

I was thinking that classes could be the safe and default but and scope/delete could be used as an optimization.

--
/Jacob Carlborg

Reply via email to