posted by Zachary Pinter on Tue 27th Apr 2004 17:09 UTC

"Garbage Collection, Page 2/2"
Parallel Copying

With the advent of multi-processor systems, many garbage collection techniques have needed multi-thread aware implementations. The parallel copying collection is a version of copying collection that runs as many threads as there are CPUs, preventing the workload from being restricted to only one CPU. The standard copying collection is unable to spread the workload to different processors, which creates an unnecessary bottleneck in performance. Compared with traditional copying collection, parallel copying has a potential speed increase by a factor equal to the number of CPUs available.

Concurrent

The concurrent approach was developed to make the application execute as seamlessly as possible alongside (and at the same time as) the garbage collector. In order to accomplish this, it must first halt all other CPU activity to mark all reachable objects. Once it has completed that operation, it creates several garbage collection threads that execute concurrently with the program based on the marked and unmarked objects. Each thread does its part to remove “garbage” objects from memory.

Parallel Scavenge

The parallel scavenge collector is similar to the parallel copying collector; however, it is optimized for large memory heaps (10GB plus) on multiple-CPU systems. The approach is designed to reduce pauses and maximize throughput. It is rarely used on anything but servers.

Finalization

Though not exactly a complete garbage collection technique, it is important to recognize how object finalization is accounted for in managed memory languages. Traditionally, languages without automated memory management (such as C++) provided destructors for their objects to free any resources that the object might consume. The terminology and syntax for finalization is similar, but the implementation is quite different. Since object “destruction” is not always explicit in different garbage collection techniques (ex: copying collection), the compiler must take extra steps to explicitly call a finalization method when an object is freed from memory. Specifically, it must maintain a list of objects with finalizers, determine when those objects are removed from memory, prevent them from being removed from memory, execute their finalize method, and then place them back into memory to be marked as “garbage” and collected once more. As you can no doubt see, finalization defeats many of the benefits of various garbage collection techniques and should only be used when absolutely necessary.

Java Implementation

Java, specifically more recent versions of the JVM, implements a two-generation (young and old) approach with different collection techniques for each generation. The default collector for the young generation is the copying collector and the default collector for the old generation is the mark-compact collector. For multiple-CPU systems, Java provides the option of a parallel copying collector or a parallel scavenge collector for the young generation and a concurrent collector for the old generation. Since the vast majority of newly created objects “die young,” Java’s use of a copying collector on the young generation and a mark-compact on the older generation appears to provide a good mix of technologies for optimal speeds.

.NET Implementation

Like Java, the .NET platform uses a multi-generational approach to garbage collection. However, it has three generations (0, 1, and 2) instead of two, with the ability to expand to even more in the future if necessary. Furthermore, where Java uses different collection techniques for different generations, .NET currently uses the mark-compact collection technique for all generations. Generation 0 is where newly created objects are placed. Objects are promoted to Generation 1 whenever they survive garbage collection on Generation 0. Similarly, when objects in Generation 1 survive garbage collection they are placed in Generation 2 and objects that survive Generation 2 garbage collection are simply compacted within Generation 2. The optimizations determining which generations to compact when are numerous and frequently changing; however, it is safe to say that Generation 0 is the most frequently compacted generation due to the short lifespan of most objects. To further optimize performance, .NET sections off a part of the heap for large objects and never compacts that section in order to prevent the CPU from wasting cycles on shifting large amounts of memory. Though .NET does not vary the techniques for collection between generations, it is clear that considerable amounts of time have been spent fine-tuning the currently employed technique for peak performance.

Conclusion

Although garbage collection can never be as efficient in every way as a well-programmed “micro-managed memory” application, it has the potential to be as efficient or even more efficient in areas that are becoming increasingly important. For example, though garbage collection might require more memory to store and more CPU time to process, it can effectively compensate in increased memory allocation speed and speedier application development. As memory becomes cheaper and CPU’s become faster, the drawbacks become even less noticeable. Furthermore, garbage collectors are continuously being optimized to bring speeds even closer to those of manual memory management. The ratio of benefit over burden for this incredible technology has finally leveled out and will only go up in the future.

References

“Automatic Garbage Collection.” Wikipedia, the free encyclopedia. 6 Apr. 2004 http://en.wikipedia.org/wiki/Automatic_garbage_collection.

Richter, Jeffrey. “Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework.” Microsoft Developer Network. 2000. Microsoft. Nov. 2000 http://msdn.microsoft.com/msdnmag/issues/1100/GCI/default.aspx.

Richter, Jeffrey. “Garbage Collection – Part 2: Automatic Memory Management in the Microsoft .NET Framework.” Microsoft Developer Network. 2000. Microsoft. Dec. 2000 http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/default.aspx.

Goetz, Brian. “Java theory and practice: A brief history of garbage collection.” IBM developerWorks. 2003. IBM. 28 Oct. 2003 http://www-106.ibm.com/developerworks/java/library/j-jtp10283/.

Goetz, Brian. “Java theory and practice: Garbage collection in the 1.4.1 JVM.” IBM developerWorks. 2003. IBM. 25 Nov. 2003 http://www-106.ibm.com/developerworks/java/library/j-jtp11253/.

Goetz, Brian. “Java theory and practice: Garbage collection and performance.” IBM developerWorks. 2004. IBM. 27 Jan. 2004 http://www-106.ibm.com/developerworks/library/j-jtp01274/.

“Question of the month: 1.4.1 Garbage collection algorithms.” Java Performance Tuning. 2003. JavaPerformanceTuning.com. 29 Jan. 2003 http://www.javaperformancetuning.com/news/qotm026.shtml.

About the Author

Zachary Pinter is a student attending the University of West Florida in Pensacola, FL. He is an aspiring programmer, OS enthusiast, and subscribed member of OSNews.


If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.
Table of contents
  1. "Garbage Collection, Page 1/2"
  2. "Garbage Collection, Page 2/2"
e p (0)    35 Comment(s)

Technology White Papers

See More