The presentation "Permanent Generation Removal Overview" on Wednesday at JavaOne 2013 shed some light on the motivation of the JVM designers and some details of the implementation when they decided to remove the Permanent Generation (PermGen) from the HotSpot JVM for JDK8. Here is a short summary of it.
There were/are some problems with PermGen that the JVM designers wanted to address.It has a fixed size that is specified at startup (-XX:MaxPermSize), so it's difficult to tune. Internal JVM types were Java objects which could move with full GC and were hard to debug. Simplification of full GCs is also desired, just like avoiding some full GC pauses caused by collecting class data which from now on should be done concurrently.
Metaspace: The New Place of Class Metadata
It is moved to the so-called Metaspace, which is part of the native memory.
Metaspace is a per classloader storage which takes advantage of the JLS property that metadata lifetimes match class loader lifetimes. This makes possible the allocation of multiple mapped virtual memory spaces with per classloader chunk lists. Class loaders are pointing to so-called metachunks residing in a specific virtual space, which in turn are pointing to another chunks in another spaces and so on. Virtual spaces are returned when emptied, and the VM applies different strategies to minimize fragmentation.
So now the object memory layout consists of the Heap for objects and the Metaspace for class metadata.
A compressed class pointer space (which is logically part of metaspace) is introduced for 64 bit platforms. For 64 bit platforms, the default behavior is using compressed (32 bit) object pointers (-XX:UseCompressedOops) and compressed (32 bit) class pointers (-XX:UseCompressedClassPointers). Whereas the compressed class pointer space contains only class metadata, the metaspace can contain all other large class metadata including methods, bytecode etc.
The maximum metaspace size can be set using the -XX:MaxMetaspaceSize flag, and the default is unlimited, which means that only your system memory is the limit. The -XX:MetaspaceSize tuning flag defines the initial size of metaspace (refer to the current PermSize parameter), and it can be set to higher than the default 21 Mb if you experience too many GCs on startup. Further memory management can be influenced with the MinMetaspaceFreeRatio and MaxMetaspaceFreeRatio parameters, which allow for fine-tuning when the collections should happen, just like with current GC FreeRatio parameters.The -XX:CompressedClassSpaceSize currently has a fixed size that can be specified on startup. JVM designers are planning to make this growable and probably set it ergonomically based on class loading predictions. The -XX:+PrintGCDetails and -XX:+PrintHeapAtGC parameters now include printing Metaspace statistics.
Improved Garbage Collection performanceA lot of complex code were removed, metadata to metadata pointers are not scanned. This means no scan and compaction time consumed. There are only a few pointers back to the heap: pointer to Class instance in class metadata and to component Class instance in array class metadata. The root scanning time is also reduced as there is no scanning of VM dictionary of loaded classes and other internal hashtables.
Monitoring and Management
For management purposes some JMX features were added. A new MXBean is introduced: the MemoryManagerMXBean with name MetaspaceManager. This is responsible for managing the two new MemoryPoolMXBeans called Metaspace and CompressedClassSpace, both of type MemoryType.NON_HEAP. They are used to report the usage of the corresponding memory spaces. In turn, the PermGen memory pool is removed from the MemoryManager MBean.
Changes in existing tools, mostly for metaspace:
- jmap -clstats (instead of jmap -permstat) to print class loader statistics,
- jstat -gc shows Metaspace instead of PermGen,
- jcmd [pid] GC.class_stats gives detailed histogram of class metadata sizes(needs -XX:+UnlockDiagnosticVMOptions),
- Mission Control, which is coming from JRockit, is the new GUI for JVM monitoring and management since 7u40.
HotSpot metadata is now allocated in Metaspace, which has new tuning flags with reasonable default values. This change of the memory model enables other class metadata and GC optimizations in the future (Class Data Sharing, G1 class unloading, metadata size reduction).
And also, something to keep in mind is that you will need to learn a bit about new JVM features and parameters when upgrading to JDK8. ;)