A non-sucking garbage collector
"Mark Hahn" <[email protected]> Sat, 17 Jul 2004 11:00:01 -0700
| Newsgroups | gmane.comp.lang.prothon.user |
|---|---|
| Message-ID | <[email protected]> |
I have figured out how to have my cake and eat it too. I have a design for the world's only garbage collector that has all the desired features with no trade-offs: 1) Mark and sweep (tracing) for tunable maximum performance including multiple cpus. 2) Continuous operation. Interpreter never stops (except for thread switching). 3) Deterministic finalization can be added based on scope. This isn't a wild-idea based on some untried technology either. The idea is to use the same tried and true technique used by file servers for backup while still serving files. ---- How it works ---- When it is time for the garbage collector to do the mark pass, it will set a global that "freezes" all objects. The object locking code will then make all existing objects read-only. When a write-lock request comes in for an object, a copy of the object is made, let's call it a write-proxy, and a pointer in the original object will point to the proxy. The changes will then be made to the proxy. New objects will be created as usual but they will be in the same class as the write-proxies. While in this freeze mode the original set of objects will exist in their frozen unchanged state exactly as they were at the moment they were flash-frozen. A new set of objects will pile up of changed and new objects. Since the "working set" of new and changed objects tends to be small and localized, there will be a surge of performance hit when the freeze first happens but pretty quickly the overhead will be reasonable. Meanwhile the garbage collector thread will be going through the frozen set of objects marking them. It will have the luxury of not using any locking code at all since the objects are all read-only. When it is done it will turn off the freeze mode. Of course the goal will be to keep the duration of the freeze mode as short as possible. When freeze mode is turned off, one might think you should go through and copy all the proxy objects back, but you really don't have to right away. Some of the proxy objects are already unreachable and should be garbage collected. So you leave them there and let read accesses use them through the indirect pointer just as they were used in freeze mode. When they happen to get write locked for any reason then you take that opportunity to copy them back which turns out to be cheaper than the original copy because their are no mallocs. The garbage collector will pick up dead ones later when it finds the dead original matching object and deletes the pair together. If memory gets low you can add a pass to the garbage collector to copy them all back to reclaim memory. ---- Cost ---- The cost of this scheme appears in two ways. One is that every object reference now must be a handle (double link) instead of a simple pointer (single link). This was going to be needed to add advanced generational garbage collector techniques anyway. The second is the already mentioned copy overhead when in freeze mode. ---- Deterministic finalization ---- The deterministic finalization can be added by a seperate mechanism Paul suggested. A seperate frame-based object collector mechanism is used in tandem with the one above that works in a Prothon frame scope only. It reclaims objects immediately that were created in a frame and never left the frame before the frame was destroyed. This is analogous to local vars on a stack in C. I will change the wiki item that is in the 1.0 list for the future to specifically describe this feature.