The removal of Metaspace began with the JEP 122.
But what was the motivation of this and where it was relocated?
Whoever worked with Java must have taken some java.lang.OutOfMemoryError: PermGen space
during a redeploy. This type of problem usually occurs due to ClassLoader
Leaks that quickly fill Permgen.
Permgem was conceived as a small space with very conservative policies of Garbage Collection (at first there was simply no GC in this area); the idea was that definitions of classes, Strings
and static variables were in a small "permanent" memory space contiguous to the heap.
In practice, however, in a world of Java EE application servers and Osgi containers (and Java EE application servers running in Osgi containers) this information is not so permanent.
Other Vms like the Jrockit (initially developed by BEA) do not implement the concept of Permgen. Jrockit VM is widely used in server side, mainly in facilities of Weblogic (significant part of Oracle’s business in the Java world). Thus, it makes sense for Oracle to converge its implementations into a single VM.
On the side of Hotspot (inherited from Sun) the solution found was to move the information that was in Permgen to a new area of native memory called Metaspace. The great advantage here is that this area can grow (and decrease), facilitating the tuning.
In practice this is part of a larger effort. Oracle is strengthening and unifying its business model with the ecosystem Oracle Java SE Advanced / Suite. The idea is for Oracle’s commercial customers to utilize the best of the BEA stack (such as the Mission Control) without Oracle having to maintain two Vms.
Is there any implication in this, for example in classloaders?
Metaspace was designed taking into account policies of Garbage Collection and Class unloading. At the time of Permgen new GC implementations always had to make some extra effort to deal with this area (which implies more switches for tuning as -XX:+CMSPermGenSweepingEnabled
and -XX:+CMSClassUnloadingEnabled
, complicated and costly Hotspot algorithms and limitations on GC ergonomics).
In the new version of Hotspot this has changed. When Metaspace reaches a certain size (i.e., memory threshold) the VM triggers the GC. The initial threshold is then adjusted as the space released (if little space has been released the threshold for GC increases if too much space has been released the threshold for GC decreases). That is, the VM tends to find a point of equilibrium between the size of Metaspace and the amount of times the GC should go into action automatically.
But what about the ClassLoader
Leaks? They keep happening of course, and as by default there are no restrictions to the size of Metaspace, these Leaks can consume all native memory / swap machine. On the positive side, instead of setting a -XX:MaxPermSize
fixed right away, you can monitor your application, examine usage spikes in Metaspace and do tuning with much more information (it is still possible to limit Metaspace with –XX:MaxMetaspaceSize
, as well as set thresholds for GC and things like that).
This also improves the ergonomics of GC and memory consumption for small applications and microservices. Permgen’s standard size was 32MB
for Vms client and 64MB
for Vms server; on my platform / VM GC already starts running when Metaspace reaches 21MB, freeing a significant amount of memory that was previously reserved. On the other hand, larger applications may suffer some Gcs unnecessary until the VM adjusts the threshold, this can be avoided by setting the initial threshold to a higher value (with the parameter -XX:MetaspaceSize
).
References:
- Where Has the Java Permgen Gone?
- Will Java 8 Solve Permgen Outofmemoryerror?
- Java 8: From Permgen to Metaspace
- About G1 Garbage Collector, Permanent Generation and Metaspace
- Metaspace in Java 8
@Anthonyaccioly Post this as an answer so I can vote for her properly. :)
– Victor Stafusa