Java 8 Metaspace Vs Permgen in Java

In this quick tutorial, we’re going to examine the differences between the PermGen and Metaspace memory regions in the Java environment.

It’s important to keep in mind that, starting with Java 8, the Metaspace replaces the PermGen – bringing some substantial changes.

PermGen

PermGen (Permanent Generation) is a special heap space separated from the main memory heap.

The JVM keeps track of loaded class metadata in the PermGen. Additionally, the JVM stores all the static content in this memory section. This includes all the static methods, primitive variables, and references to the static objects.

Furthermore, it contains data about bytecode, names, and JIT information. Before Java 7, the String Pool was also part of this memory. The disadvantages of the fixed pool size are listed in our write-up.

The default maximum memory size for 32-bit JVM is 64 MB and 82 MB for the 64-bit version.


However, we can change the default size with the JVM options:

-XX:PermSize=[size] is the initial or minimum size of the PermGen space

-XX:MaxPermSize=[size] is the maximum size

Most importantly, Oracle completely removed this memory space in the JDK 8 release. Therefore, if we use these tuning flags in Java 8 and newer versions, we’ll get the following warnings:

>> java -XX:PermSize=100m -XX:MaxPermSize=200m -version

OpenJDK 64-Bit Server VM warning: Ignoring option PermSize; support was removed in 8.0

OpenJDK 64-Bit Server VM warning: Ignoring option MaxPermSize; support was removed in 8.0

...

With its limited memory size, PermGen is involved in generating the famous OutOfMemoryError. Simply put, the class loaders weren’t garbage collected properly and, as a result, generated a memory leak.

Therefore, we receive a memory space error; this happens mostly in the development environment while creating new class loaders.

Metaspace

Simply put, Metaspace is a new memory space – starting from the Java 8 version; it has replaced the older PermGen memory space. The most significant difference is how it handles memory allocation.

Specifically, this native memory region grows automatically by default.

We also have new flags to tune the memory:

MetaspaceSize and MaxMetaspaceSize – we can set the Metaspace upper bounds.

MinMetaspaceFreeRatio – is the minimum percentage of class metadata capacity free after garbage collection

MaxMetaspaceFreeRatio – is the maximum percentage of class metadata capacity free after a garbage collection to avoid a reduction in the amount of space

Additionally, the garbage collection process also gains some benefits from this change. The garbage collector now automatically triggers the cleaning of the dead classes once the class metadata usage reaches its maximum metaspace size.

Therefore, with this improvement, JVM reduces the chance to get the OutOfMemory error.

Despite all of these improvements, we still need to monitor and tune the metaspace to avoid memory leaks.


From Java Nexus:-

Managing Memory in Java 8: Understanding Metaspace

When it comes to memory management in Java, the introduction of Metaspace in Java 8 brought significant changes to how memory is allocated for class metadata. Understanding Metaspace is essential for Java developers to optimize memory usage and prevent issues such as OutOfMemory errors. In this blog post, we'll dive into the concepts of Metaspace, explore its differences from the previous PermGen space, and discuss best practices for managing Metaspace in Java 8.


What is Metaspace?

In Java 8, the permanent generation (PermGen) was replaced by Metaspace. Metaspace is a part of the native memory and is not part of the Java heap. It is responsible for holding the class metadata, such as class information, method data, method code, and other static information. Unlike PermGen, Metaspace can dynamically resize itself based on the application's demand.


Differences Between Metaspace and PermGen

Dynamic Sizing

One of the most significant differences between Metaspace and PermGen is the dynamic sizing capability of Metaspace. In the PermGen space, the size was fixed, leading to potential issues when the number of classes or classloaders increased. Metaspace, on the other hand, can expand or shrink based on the application's metadata requirements, providing more flexibility and reducing the risk of running out of memory due to class metadata.


Garbage Collection

In PermGen, the garbage collection was mainly responsible for reclaiming space from class metadata and interned String objects. With Metaspace, the garbage collection is triggered when the metadata usage exceeds a certain threshold, and it mainly focuses on reclaiming unused class metadata. This change reduces the likelihood of PermGen-related memory leaks and simplifies the memory management process.


Configuration

Unlike PermGen, which required manual configuration of the initial and maximum size, Metaspace is by default limited by the amount of native memory available to the Java process. However, developers can still configure the initial and maximum Metaspace size using command-line options such as -XX:MetaspaceSize and -XX:MaxMetaspaceSize to fine-tune memory allocation for class metadata.


Best Practices for Managing Metaspace

Monitoring Metaspace Usage

To effectively manage Metaspace, it's crucial to monitor its usage. Tools like JConsole, VisualVM, or Java Mission Control can provide insights into Metaspace utilization, including the amount of used and available space, the number of classes loaded, and the frequency of garbage collection. Monitoring these metrics allows developers to detect potential memory issues and make informed decisions about memory optimization.


Analyzing Class Metadata Footprint

Understanding the footprint of class metadata in Metaspace is essential for identifying potential memory inefficiencies. Tools like Java VisualVM with the Visual GC plugin or the -XX:+PrintClassHistogram JVM option can help analyze the memory consumption of class metadata, including the size of loaded classes and their dependencies. By identifying excessively large or unnecessary class metadata, developers can optimize memory usage and reduce the risk of Metaspace exhaustion.


Optimizing Class Loading

Efficient class loading plays a significant role in managing Metaspace. Avoiding unnecessary class loading, reducing the number of classloaders, and optimizing the loading of third-party libraries can contribute to a more efficient use of Metaspace. Additionally, using techniques like class data sharing (CDS) can improve startup time and reduce Metaspace usage by sharing common class metadata among multiple Java processes.


Tuning Metaspace Size

While Metaspace dynamically sizes itself based on demand, developers can still benefit from tuning its size based on specific application requirements. By analyzing the application's class metadata usage patterns and considering factors such as the number of unique classes and the frequency of class loading, developers can adjust the initial and maximum Metaspace size to prevent excessive resizing and potential memory fragmentation.


Example: Configuring Metaspace Size

To illustrate the process of configuring Metaspace size, consider the following Java command-line options:

java -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=256m MyApp

In this example, we set the initial Metaspace size to 64 megabytes and the maximum Metaspace size to 256 megabytes for the MyApp application. By defining these parameters, we provide explicit guidance to the JVM on the allocation of native memory for class metadata, preventing unexpected Metaspace expansions and ensuring adequate memory for class loading requirements.


Bringing It All Together

Understanding and effectively managing Metaspace is essential for optimizing memory usage and preventing memory-related issues in Java 8 applications. By grasping the differences between Metaspace and PermGen, monitoring Metaspace usage, analyzing class metadata footprint, optimizing class loading, and tuning Metaspace size, developers can proactively address memory management challenges and ensure the stability and performance of their Java applications.


In conclusion, with Metaspace's dynamic sizing, improved garbage collection, and configurable options, Java developers have more flexibility and control over memory management, paving the way for efficient and robust Java applications in the modern era.


By incorporating these best practices and staying informed about memory management advancements in Java, developers can leverage Metaspace to its full potential and build resilient and high-performing Java applications.


Remember, understanding the inner workings of memory management, including Metaspace, is crucial for mastering Java development and delivering top-notch software solutions.


For further reading on Metaspace and memory management in Java, check out the official Java Memory Management Guide provided by Oracle.


With the right knowledge and practices, Java developers can harness the power of Metaspace to unlock new levels of memory efficiency and application performance. Cheers to optimized memory management in Java 8!