A few considerations on garbage collection
Andrei Alexandrescu via Digitalmars-d
digitalmars-d at puremagic.com
Wed Apr 30 08:33:25 PDT 2014
I'm mulling over a couple of design considerations for allocators, and
was thinking of the following restriction:
1. No out-of-bounds tricks and no pointer arithmetic. Consider:
int[] a = new int[1000];
a = a[250 .. 750];
int* p = a[500 .. $].ptr;
Subsequently the GC should be within its rights to deallocate any memory
within the first and last 250 integers allocated, even though in theory
the user may get to them by using pointer arithmetic.
In particular that means once a slice is shrunk, there's no growing back
unless another slice is around.
I think the current GC already does that.
2. The same may be the case for classes WITHOUT destructors. Consider:
class A
{
int[1000] a;
int b;
int[1000] c;
}
int* p = &(new A).b;
The collector should be allowed to deallocate any memory except b's own,
even though that means the class has "holes" in it. The current GC does
not do that.
2. However, the same shall not be the case for classes with destructors.
Consider:
class B
{
int[1000] a;
int b;
int[1000] c;
~this() { ... }
}
int* p = &(new B).b;
This class has a destructor, so it will be kept around in its entirety
if an internal pointer is held.
3. Classes meant to have destructors called at collection will ALWAYS
have been allocated with new (i.e. won't start in the middle of some
other allocation). In other words, only class objects created with new
will be properly collected. Those forced in odd places with emplace()
are the responsibility of the user.
4. Currently, struct objects created with new do NOT have their
destructors called during collection. I think this may continue, meaning
that structs created with new are somewhat low-level and are meant to be
destroyed and deallocated manually.
5. This brings up arrays of structs. As far as I understand, destructors
will never be called for these, even after all references are gone:
struct S { ~this() { ... } }
auto a = new S[100];
Unlike (4), arrays of structs are high-level and frequently used. I
think we must do something about it, so I plan to support calling
destructors for arrays of structs.
6. The point above brings to mind more radical possibilities, such as
making all arrays reference-counted and allowing compulsive deallocation
when the reference counter goes down to zero. That would rule out things
like escaping pointers to data inside arrays, which is quite extreme.
But probably worth bringing up in a brainstorming. If we disallow
statically constructs that take addresses we may get away with it.
Please chime in with your thoughts.
Andrei
More information about the Digitalmars-d
mailing list