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