The major concepts in Java Memory Management :
- JVM Memory Structure
- Working of Garbage Collector
JVM defines various run time data area which are used during execution of a program. Some of the areas are created by the JVM whereas some are created by the threads that are used in a program. However, the memory area created by JVM is destroyed only when the JVM exits. The data areas of thread are created during instantiation and destroyed when the thread exits.
JVM Memory area parts
These parts of the memory area in detail:
- It is a shared runtime data area and stores the actual object in a memory. It is instantiated during the virtual machine startup.
- This memory is allocated for all class instances and array. Heap can be of fixed or dynamic size depending upon the system’s configuration.
- JVM provides the user control to initialize or vary the size of heap as per the requirement. When a new keyword is used, object is assigned a space in heap, but the reference of the same exists onto the stack.
- There exists one and only one heap for a running JVM process.
Scanner sc = new Scanner(System.in);
The above statement creates the object of Scanner class which gets allocated to heap whereas the reference ‘sc’ gets pushed to the stack.
Note: Garbage collection in heap area is mandatory.
- It is a logical part of the heap area and is created on virtual machine startup.
- This memory is allocated for class structures, method data and constructor field data, and also for interfaces or special method used in class. Heap can be of fixed or dynamic size depending upon the system’s configuration.
- Can be of a fixed size or expanded as required by the computation. Needs not to be contiguous.
Note: Though method area is logically a part of heap, it may or may not be garbage collected even if garbage collection is compulsory in heap area.
- A stack is created at the same time when a thread is created and is used to store data and partial results which will be needed while returning value for method and performing dynamic linking.
- Stacks can either be of fixed or dynamic size. The size of a stack can be chosen independently when it is created.
- The memory for stack needs not to be contiguous.
PermGen vs MetaSpace
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 JDK 8 release.
With its limited memory size, PermGen is involved in generating the famous OutOfMemoryError. Simply put, the class loaders aren’t garbage collected properly and, as a result, generated a memory leak.
Therefore, we receive a memory space error; this happens mostly on development environment while creating new class loaders.
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 the memory allocation.
As a result, this native memory region grows automatically by default. Here we also have new flags to tune-up 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 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 this improvements, we still need to monitor and tune up the metaspace to avoid memory leaks.