From: Kurt  Stephens <ks.ruby@...>
Date: 2011-11-02T03:57:36+09:00
Subject: [ruby-core:40642] [ruby-trunk - Feature #5494] Proposal: Improved Finalizer Semantics


Issue #5494 has been updated by Kurt  Stephens.


Kurt  Stephens wrote:
> Nobuyoshi Nakada wrote:
> > Even if the object has not been freed, other objects referred by the
> > object might be freed already.  It has to sort topologically the
> > directed graph, even for simple cases.  Not only this would be quite
> > expensive, cyclic references cannot sort.
> 
> Good point.  It would have to re-MARK the object and its references, recursively, to be safe.

Clarifications:

* The idea is to run finalizers (and re-MARK) after root marking, and before sweep.  Thus, it would work with lazy sweep.
* The MARK operation on the finalized object is the *exact* same recursive MARK operation that already exists in gc.c.
* The semantics I described is exactly how (most) JVMs implement finalizations.  It's also how I implemented finalizations in SMAL.
* We can keep the proc.call(obj.id) API, until the proc.call(obj) API change is acceptable.



----------------------------------------
Feature #5494: Proposal: Improved Finalizer Semantics  
http://redmine.ruby-lang.org/issues/5494

Author: Kurt  Stephens
Status: Rejected
Priority: Normal
Assignee: 
Category: 
Target version: 3.0


Proposal: Improved Finalizer Semantics:

ObjectSpace.define_finalizer(object, proc):
** proc should have a single parameter, the object to be finalized, not its id.

When an object with a finalizer is no longer referenced (sweepable):
* The object is reconsidered to be REFERENCED until next GC.
* It's finalizer proc(s) are called, only once, with the object as the sole argument.
* Subsequently, the finalizer procs are removed from the object.
* The object's memory will *NOT* be reclaimed yet, nor will its C free_proc be called, 
  since calling the finalizer proc effectively creates new (temporary) references to the object.
* If the finalizer did *NOT* create any additonal, long-term references to the object, 
  the object's memory and low-level C resources will be reclaimed in the next GC.

This is a simpler protocol: 

* It removes the need for _id2ref in the finalizer procs.
* Prevents other complications: such as GC being reinvoked within a finalizer.
* Finalizers are invoked with the same "urgency" as before.

The downside:

* Objects with finalizers actually live for more than one GC cycle, if they are unreferenced.
* This is probably acceptable since the resources the finalizers "clean-up"
(eg.: file descriptors in a File object) are generally more scarce than the objects holding them.






-- 
http://redmine.ruby-lang.org