This is getting to be fun, but afraid I can only make time for the first easy one tonight: [Tim, conjures a horrid vision of finalizers installing new __del__ methods, then sez ... ] > The scheme above is meant to be bulletproof in the face of abuses even > I can't conceive of <wink>. [Guido] > Are you *sure* your scheme deals with this? Never said it did -- only that it *meant* to <wink>. Ya, you got me. The things I thought I had *proved* I put in the numbered list, and in a rush put the speculative stuff in the reply body. One practical thing I think I can prove today: after finding SCCs, and identifying the safe nodes without predecessors, all such nodes S1, S2, ... can be cleaned up without fear of resurrection, or of cleaning something in Si causing anything in Sj (i!=j) to get reclaimed either (at the time I wrote it, I could only prove that cleaning *one* Si was non-problematic). Barring, of course, this "__del__ from hell" pathology. Also suspect that this claim is isomorphic to your later elaboration on why the objects on T at this point cannot be resurrected by a finalizer that runs, since they aren't reachable from any finalizers That is, exactly the same is true of "the safe (SCC super)nodes without predecessors", so I expect we've just got two ways of identifying the same set here. Perhaps yours is bigger, though (I realize that isn't clear; later). > Let's look at an example. > (Again, lowercase nodes have no finalizers.) Take G: > > a <=> b -> C > > [and cleaning b can trigger C.__del__ which can create > a.__class__.__del__ before a is decref'ed ...] > > ... and we're halfway committing a crime we said we would never commit > (touching cyclical trash with finalizers). Wholly agreed. > I propose to disregard this absurd possibility, How come you never propose to just shoot people <0.9 wink>? > except to the extent that Python shouldn't crash -- but we make no > guarantees to the user. "Shouldn't crash" is essential, sure. Carry it another step: after C is finalized, we get back to the loop clearing b.__dict__, and the refcount on "a" falls to 0 next. So the new a.__del__ gets called. Since b was visible to a, it's possible for a.__del__ to resurrect b, which latter is now in some bizarre (from the programmer's POV) cleared state (or even in the bit bucket, if we optimistically reclaim b's memory "early"!). I can't (well, don't want to <wink>) believe it will be hard to stop this. It's just irksome to need to think about it at all. making-java's-gc-look-easy?-ly y'rs - tim
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4