How do the different Java implementations compare in terms of their garbage collectors?

John Zukowski

How Java technology does garbage collection is dependent on the implementation you are using. Four algorithms commonly used and how they typically work are as follows:

  • Mark and Sweep - Follow all reference variables (starting with static and stack variables), marking memory used along the way. Anything that isn't marked after all paths are followed is swept away. Periodically, memory space must be compacted as holes of varying size develop.
  • Stop and Copy - Stop everything and copy all referenced data into a new area. Anything not copied is automatically reclaimed as the original space is discarded. This requires twice as much available memory because of the copying involved.
  • Reference Counting - Keeps a counter along with every block of memory allocated. When a reference is added to the memory block, the counter is increased. When a reference is removed, the counter is decremented. When the counter reaches zero, the block of memory is automatically placed in the free memory area, as there are no references to it. This requires synchronization overhead for updating the reference count and must detect circular references, somehow.
  • Generational - Groups objects by generations, based on creation time. Since recently created objects tend to be more short-lived, able to reduce amount of compaction necessary, or at least reduce frequency of moving long-lived objects.

If memory serves me correctly, the basic Sun JRE uses Mark and Sweep while Microsoft's JRE uses Stop and Copy. Generational is more of an optimization technique of Mark and Sweep and not usable with Stop and Copy. I'm not aware of any implementation that uses Reference Counting.

For more information on garbage collection, see the Garbage Collection: Algorithms for Automatic Dynamic Memory Management book from Richard Jones and Rafael Lins.