Re: Hiding the effect of concurrent finalization
"Boehm, Hans" <[email protected]> Thu, 11 Feb 2010 18:39:56 +0000
| Newsgroups | gmane.comp.programming.garbage-collection.general |
|---|---|
| Message-ID | <238A96A773B3934685A7269CC8A8D042578414CEFC@GVW0436EXB.americas.hpqcorp.net> |
> From: Florian Weimer >=20 > I've recently come across a rather puzzling problem and I=20 > wonder if it has been discussed before. Suppose you have got=20 > a language which sports garbage collection, scope-based=20 > automatic resource management (like the WITH- pattern in=20 > Common Lisp, or C#'s "using" construct), and coroutines=20 > (user-scheduled threads, also called one-shot continuations,=20 > I believe), but not (explicit) user-defined finalizers. > Unfinished Coroutines are not automatically part of the root=20 > set (this is different from Java threads, for instance.) >=20 > The problem I have is what happens if a coroutine object is=20 > garbage-collected, but there are still stack frames on it,=20 > including some which involve automatic resource management. =20 > Presumably, the associated cleanup code needs to be executed=20 > when the coroutine object becomes unreachable. But this=20 > means that we now have a generic, user-defined finalizer=20 > facility. And this seems to be unavoidable. >=20 > Consequently, I wonder if there are any good ways of hiding=20 > the concurrent nature of finalization. One idea that comes=20 > to my mind is to run finalizers for objects of a specific=20 > type only when new objects of that type are created. Are=20 > there any better ideas? The standard solution for single-thread environments seems to be to put rea= dy-to-be-run finalizers into a queue, and then require the user to explicit= ly take some action to run those, ideally when nothing else is going on, an= d none of the data structures updated by finalizers are currently being upd= ated by the mainline code. Java.lang.ref takes a similar approach, even in= a multithreaded context. My (unproven) intuition is that running finalizers for T when a T is being = allocated is relatively likely to run finalizers when the underlying data s= tructures are already in use, and thus perhaps more likely to break things = than running them in response to a random allocation. I wouldn't recommend= either. (We currently do the latter by default, for historical reasons, a= nd it works in the simplest cases, but I still wouldn't recommend it.) Is it possible to run into the same kind of premature finalization issues d= escribed in my 2003 POPL paper? I think that restricting yourself to a sin= gle thread makes this less likely, but not impossible. That might be an ev= en scarier problem, in that it's probably very difficult to provoke in prac= tice in this context, but handling it cleanly may require prohibiting dead = pointer variable elimination in the compiler. Hans >=20 > (The Scheme approach involving callbacks for entering and=20 > exiting the protected scope does not seem to reflect reality=20 > that well; it is not always possible to gain access to the=20 > same resource after releasing it. For instance, a file might=20 > have been deleted in the meantime.) > =