auto classes and finalizers
Bruno Medeiros
brunodomedeirosATgmail at SPAM.com
Thu Apr 13 11:53:30 PDT 2006
Sean Kelly wrote:
> Bruno Medeiros wrote:
>> Sean Kelly wrote:
>>
>>> A possible alternative would be for the GC to peform its cleanup in
>>> two stages. The first sweep runs all finalizers on orphaned objects,
>>> and the second releases the memory. Thus in Eric's example on
>>> d.D.learn, he would be able legally iterate across his AA and close
>>> all HANDLEs because the memory would still be valid at that stage.
>>>
>>
>> By orphaned objects, do you mean all objects that are to be reclaimed
>> by the GC on that cycle? Or just the subset of those objects, that are
>> not referenced by anyone?
>
> All objects that are to be reclaimed. I figured your other suggestion
> could be used for more complex cases.
>
That way, you have the guarantee that all references are valid, but some
instances would have their destructors called multiple times. That's
likely a behavior that isn't acceptable on some cases.
>>>> Another interesting addition, is to extend the concept of auto to
>>>> class members. Just as currently auto couples the lifecycle of a
>>>> variable to the enclosing function, an auto class member would
>>>> couple the lifecycle of its member to it's owner object. It would
>>>> get deleted implicitly when then owner object got deleted. Here is
>>>> another (made up) example:
>>>>
>>>> class SomeUIWidget {
>>>> auto Color fgcolor;
>>>> auto Color bgcolor;
>>>> auto Size size;
>>>> auto Image image;
>>>> ...
>>>>
>>>> The auto members would then have to be initialized on a constructor
>>>> or something (the exact restrictions might vary, such as being final
>>>> or not).
>>>
>>> I like this idea as well, though it may require some additional
>>> bookkeeping to accomplish. For example, a GC scan may encounter the
>>> members before the owner, so each member may need to contain a hidden
>>> pointer to the owner object so the GC knows how to sort things out.
>>
>> Hum, true, it would need some additional bookkeeping, didn't realize
>> that immediately. The semantics like those that I mentioned in me
>> previous post would suffice:
>>
>> "When a destructor is called upon an object during a GC (i.e., "as a
>> finalizer"), then the member references are not valid and cannot be
>> referenced, *but they can be deleted*. Each will be deleted iff it has
>> not been deleted already in the reclaiming phase."
>>
>> I don't think your algorithm (having a hidden pointer) would be
>> necessary (or even feasible), and the one I mentioned before would
>> suffice.
>
> Hrm... but what if the owner is simply collected via a normal GC run? In
> that case, the GC may encounter the member objects before the owner
> object. I suppose bookkeeping at the member level may not be necessary,
> but it may result in an extra scan through the list of objects to be
> finalized to determine who owns what.
>
>
> Sean
The bookkeeping is made by the GC and memory pool manager. A scan
through the list of objects to be finalized is necessary, but it won't
be an _extra_ scan. Let me try to explain this way:
*** The current GC algorithm: ***
delete obj:
m = getMemManagerHandle(obj);
if(m.isObjectInstance)
m.obj.destroy(); // calls ~this()
freeMemory(m);
GC:
GC determines a set S of instances to be reclaimed (garbage);
foreach(m in S) {
delete m;
}
*** The extended GC algorithm: ***
delete:
m = getMemManagerHandle(obj);
if(m.isDeleted)
return;
if(m.isObjectInstance)
m.obj.destroy(); // calls ~this()
if(!m.isGarbageSet) // If it is not in S
freeMemory(m);
GC:
GC determines a set S of instances to be reclaimed (garbage);
foreach(m in S) {
m.isGarbage = true;
}
foreach(m in S) {
delete m;
}
foreach(m in S) {
freeMemory(m);
}
And there we go. No increase in algorithmic complexity. There is only an
increase in the Memory Manager record size (we need a flag for
m.isDeleted, and we need it only during a GC run).
The reason we don't freeMemory(m) right after delete m; is because we
need the bookkeeping of m.isDeleted until the end of the GC run.
The reason we have m.isGarbage is to allow the deletion of objects not
in S during the GC run. (it is an optimization of doing "S.contains(m)" )
Hope I don't have a bug up there :P
--
Bruno Medeiros - CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
More information about the Digitalmars-d
mailing list