We’ve covered quite a bit about the JVM, but today we’re going to cover some of the areas that we haven’t covered in detail, such as persistent generations and meta-spaces.

The permanent generation

Java has a part of memory called the method area, and prior to JDK8, the Hotspot virtual machine was implemented as Permanent Generation, which no other JVM has.

In the past (when custom classloaders were not common), classes were almost “static” and rarely unloaded or recycled, so classes could be considered “permanent.” In addition, because classes are part of the JVM implementation, they are not created by programs because they are also considered “non-heap” memory.

The permanent generation is a contiguous memory space that can be controlled before the JVM starts by setting -xx :MaxPermSize. The default size of the permanent generation is 64M for 32-bit machines and 85M for 64-bit machines.

Garbage collection for the permanent generation is tied to garbage collection for the old generation, and once one of the areas is occupied, both areas are collected. But there is an obvious problem, because we can through ‑ XX: MaxPermSize set the size of the permanent generation, once the metadata of the class more than the size of the set, the program will run out of memory, and memory overflow error (Java. Lang. OutOfMemoryError: PermGen space).

Why does class metadata take up so much memory? In the HotSpot VIRTUAL machine prior to JDK7, strings that were included in the string constant pool were stored in the persistent generation, resulting in a number of performance issues and memory overflow errors.

To address these performance issues, and to enable Hotspot to be managed like any other virtual machine, a meta-space was created.

dimension

Metaclase is a new addition to Hotspot in JDK8, similar in nature to the permanent generation, which is an implementation of the method area in the JVM specification. But the biggest difference between a metaclspace and a permanent generation is this:

The meta-space is not in the virtual machine, but uses local memory. Therefore, by default, the size of a meta-space is limited only by local memory, but you can specify the size of a meta-space with the following parameters:

-XX:MetaspaceSize

> Initial space size, which triggers garbage collection for type offloading and is adjusted by GC: if a large amount of space is freed, it is reduced; If very little space is freed, increase this value appropriately until MaxMetaspaceSize is exceeded.

  

-XX:MaxMetaspaceSize

> Maximum space, default is unlimited.

In addition to the two options above to specify the size, there are two gC-related attributes:

-XX:MinMetaspaceFreeRatio

> The minimum percentage of Metaspace free space capacity after GC, reducing the garbage collection caused by allocating space

-XX:MaxMetaspaceFreeRatio

> The maximum percentage of Metaspace free space capacity after GC, reduced to garbage collection resulting from free space

Remove the effect of permanent generation

Since the metadata of a class is allocated in local memory, the maximum allocatable space of the metadata space is the memory space available to the system. As a result, we don’t experience memory overflow errors with persistent generations, and we don’t have things like leaked data moving to swap. End users can set a maximum amount of free space for the meta-space; if this is not set, the JVM automatically dynamically increases the size of the meta-space based on the metadata size of the class.

Note: The removal of the permanent generation does not mean that the custom classloader leak problem is solved. Therefore, you also have to monitor your memory consumption, because a leak can take up a lot of your local memory and can make swap swap worse.

Meta space memory management

The memory management of the meta-space is done by the meta-space virtual machine.

Previously, we needed a different garbage collector for class metadata. Now we just need to execute the C++ code of the meta-space virtual machine to do this. In a meta-space, the life cycle of a class and its metadata is the same as that of its corresponding classloader. In other words, as long as the classloader is alive, the metadata for the classes it loads is also alive and therefore not recycled.

To be precise, each class loader’s storage area is called a meta-space, and all of the meta-spaces taken together are what we always call a meta-space. When a classloader is marked by the garbage collector as no longer alive, its corresponding meta-space is reclaimed. There are no operations such as relocation and compression during the reclamation of the metacolor. But the metadata in the metadata space is scanned for Java references.

How is it managed?

Metaspace VMS are responsible for allocating metaspace in the form of block allocation. The size of the block varies with the type of class loader. There is a global list of free blocks in a meta-space virtual machine.

  1. When a classloader needs a block, it gets and maintains its own block list from this global block list.
  2. When a classloader is no longer alive, its holding blocks are released and returned to the global block list.
  3. The blocks held by the class loader are then divided into blocks, each of which stores a unit of meta-information. Blocks in blocks are allocated linearly (in the form of pointer collision allocation). Blocks are allocated from memory-mapped areas. These global virtual memory mapped areas are connected in a linked list that is returned to the operating system once a virtual memory mapped area is cleared.

Run-time constant pool

The runtime constant pool is part of the method area in JDK6 and previous JVMS, whereas the method area implementation in the HotSpot VIRTUAL machine is Permanent Generation. So the runtime constant pool is also in the persistent generation.

However, JVMS in JDK7 and later versions have removed the string constant pool from the method area, creating an area in the Heap for the runtime constant pool.

String. Intern () is a Native method that returns a reference to a String in the constant pool if the runtime constant pool already contains a String equal to the String. If not, a String with the same contents as this String is created in the constant pool and a reference to the String created in the constant pool is returned.

Existing problems

As mentioned earlier, metaspace virtual machines take the form of block allocation, and the size of the block is determined by the class loader type. The class information is not fixed size, so it is possible to allocate a free block of a different size than the block required by the class, in which case fragmentation can exist. Metaspace virtual machines currently do not support compression operations, so fragmentation is currently the biggest problem.

conclusion

The permanent generation has been optimized into a meta-space because it is easy to generate OOM, but even then, there is still a question, I don’t know how the JDK will be optimized after?

If you are interested, you can visit my blog or pay attention to my public number and headline number. Maybe there will be unexpected surprises.

death00.github.io/