Re: Finalizers & Reference counting.
Andrew Shi-hwa Chen <[email protected]>
| Newsgroups | gmane.comp.programming.garbage-collection.general |
|---|---|
| Message-ID | <[email protected]> |
In Objective-C, something similar is done, except instead of GC it is programmer-explicit RC, but the notion of "ad" as you refer to it corresponds to an NSAutoReleasePool. -- Andrew Chen [email protected] > This whole discussion does bring up an interesting point, however. Some > programs - compilers are a great example - go through phases with the > property that: > > a) Each phase allocates and manipulates a significant amount of > memory, much of which remains live throughout the phase; > > b) Much of the memory allocated in a phase goes dead when the > phase ends. > > (In many cases, the "much" memory is actually identifiable at the point of > allocation.) > > The classic method to deal with this in a non-GC environment is to support > the notion of an allocation domain (various name have been used for this). > Each phase creates an AD, and phase-specific memory is allocated from the > AD. At the end of the phase, the entire AD is deleted, normally using a > fast mechanism that is often essentially independent of the number of > allocated blocks in the AD. In a very simple case, an AD is a block of > contiguous memory, allocations just "bump the pointer", and deleting an AD > simply requires deleting the large block, ignoring its content. This can be > surprisingly effective if AD-allocated memory is rarely deleted within the > phase. (It also helps cache/working set locality.) > > The question is: How could you capture the same advantages in a GC'ed > system? It seems that AD's, in some ways, are similar to generations. > However, generations have the wrong lifetime semantics: Anything we would > likely have put into an AD will probably get promoted to a generation that > will stick around for long after the phase ends. Still, the basic > *techniques* used to implement generational collection could perhaps be used > here. > > Thus, imagine that, in a GC'ed system, we retain the same three user > visible primitives: > > ad <- createAD() > pointer <- allocate(size,ad) > destroy(ad) > > We would like destroy() to be fast, as immediate as possible, but of course > safe. If we maintain the invariant that no pointer to an object in an > AD can come from outside the AD, then destroy() becomes trivial - just put > everything in the AD - or the whole AD, if you allocate it as a big chunck - > on the free list. This should be implementable with write barriers. (There > are, of course, subtleties like allowing register and stack pointers to > *not* force stuff out of the AD, or everything will wander out of it rapidly.) > > I'm sure a complete design and implementation would reveal all kinds of > issues. Has anyone ever looked at this kind of "hinted" GC? > > -- Jerry