Heap and Garbage-Collector Tuning
Garbage collection in Java operates incrementally on separate generations of objects rather than on all objects every time. As with escape analysis, most objects are only needed for a short duration and quickly become eligible for garbage collection. Since J2SE 1.2, the heap has been divided into a young and old generation. The young generation quickly fills up with fresh objects and is garbage collected efficiently without analyzing objects in the old generation. The entire heap is garbage collected only when the old generation reaches a certain capacity. Java 5.0 adds the ability to customize the sizes of specific generations in memory and set ratios for when garbage collections should be performed.
Java 5.0 adds a permanent generation for VM data that is never garbage collected. Information about classes and methods is stored in the permanent generation. This separation makes garbage collections faster by not analyzing permanent data. Unfortunately, the permanent generation can run out of space independent of the traditional heap. If a large number of classes are going to be loaded in the VM, it is recommended to increase the permanent generation size using a VM argument. Otherwise, a "java.lang.OutOfMemoryError: PermGen space" is thrown by the VM. This argument increases the total space for permanent memory to 128 MB:
-XX:PermSize=128m
The permanent generation is particularly useful with class data sharing in Java 5.0. The information about classes and methods can be dumped from the permanent generation to disk and reloaded straight into memory upon the next VM startup. This saves time by not recalculating that information from class files. The end result is that the VM startup time is much faster in Java 5.0 when the permanent class information has been calculated once already.
Other memory characteristics for garbage collection are determined automatically based on machine hardware when no arguments are explicitly provided. Every Java application adheres to its own unique memory pattern. Java garbage collection and memory settings should be adjusted to find the optimal settings for each application. Typical options are optimized for memory and performance profiles of small application startup or server throughput. Sun's web site provides more information on the options and strategies for tuning garbage collection in recent Java versions. It is important to adjust garbage collection and memory settings for every Java application because each will have a slightly different memory profile.
Conclusion
Sun has Java evolution on the right track. Each new version of the Java Runtime Environment (JRE) contains optimizations to execute existing Java code faster than was previously possible. Each new version of the JDK contains additions to the API that future programs can use for even better performance. Widespread exposure to the performance improvements in Java 5.0 and later should dispel the urban legend that interpreted languages are always slow.