View Single Post
Capt'n Corrupt's Avatar
Posts: 3,524 | Thanked: 2,958 times | Joined on Oct 2007 @ Delta Quadrant
#203
This site points out a problem that I had not considered with the reference counting scheme. If you have a pair of objects referencing each other, but inaccessible to the root tree they will never be de-allocated, and thus the memory is as good as leaked:
http://www.morefor.org/documentation/gc.html

This is a very serious problem. But is there a simple solution to this? Sure.

I refer to these pockets of circular referencing objects as bubbles.

This 'bubble' of references inaccessible to the root tree can be determined quite readily if we know all points of connection to the root tree, and upon de-allocation, we traverse the bubble to decrease the root-count of the 'child' objects. The trick is to know all of the objects during the search so that decrementing the reference count excludes objects in the bubble pointing to one another! Once this count reaches zero, we know with certainty that the object is inaccessible regardless if it's part of a bubble!

After that, it's simple counting and traversal, and requires no pause of a running system as this can be done asynchronously with the program on a de-prioritized thread, just so long as you maintain a stack of to-be-dealt-with de-allocations and a single Garbage Collector is in operation. There is no need to suspend the application for clean-up.

This works.

This is slightly different than simple reference counting, and requires a slightly more complex allocation/de-allocation procedure and additional object storage. However, the cost is still quite minimal, and with the right structure, and would save copious amounts of runtime performing the GC by eliminating the need for a periodic traversal of the root tree (mark-sweep).

Memory fragmentation is another problem. The only thing I can think of at the moment is to maintain a 'doubly linked list' of objects and their referrers, so that object re-location can have all referrer object references updated. Since we have a structure of the object tree, this should be easy. Also, the use of a temporary virtual address at the old object offset can stand in for the object until all referrer's references have been mended (can this be accomplished without a test?). This eliminates the need to pause operations during a relocation!