Search code examples
concurrencygarbage-collectioneiffel

Eiffel concurrent garbage collection


Can anyone explain how the concurrent garbage collection is implemented in eiffel ? What i found are details regarding garbage collection for sequential programs: - generation scavaging - mark and sweep - memory compaction

Does Eiffel handle the concurrent (using SCOOP) garbage collection differently? Using SCOOP the heap is divided in regions for each separate objects. Which are the criteria to deallocate a specific object?


Solution

  • The major difference of a SCOOP-aware garbage collector from a regular one is that it removes not only objects but also releases SCOOP processors/regions. Live objects are traced starting from the root sets that include objects reachable from call stacks and once function results. The first ones (call stacks) are unconditional, i.e. are always included in the root sets because the corresponding objects are involved in some computation. The second ones (once function results) are conditional, because they should be taken into account only when the corresponding processor/region is also reachable. As a result, the GC should track both live objects and live processors/regions.

    When a processor/region becomes unreachable, the associated thread and resources should be freed. Therefore, the garbage collector releases not only memory but also computing power. Given that live objects and live processors/regions are interdependent, the algorithm computes a fixed point for live objects and live processors/regions. This is different from a traditional GC that computes a fixed point only for live objects. After this computation the SCOOP-aware GC reclaims dead objects and dead processors. A detailed decription of the algorithm with some benchmarks can be found in a paper "Processors and Their Collection".

    As to the object garbage collection, the implementation in EiffelStudio currently uses the algorithm you mention: generational scavenging, mark and sweep, memory compaction with a traditional adaptation to multithreading, when writes to already processed objects are recorded and taken into account by the GC.