OutOfMemoryError系列(4): Metaspace
This is the fourth article in this series, a list of related articles:
- OutOfMemoryError系列(1): Java heap space
- OutOfMemoryError系列(2): GC overhead limit exceeded
- OutOfMemoryError系列(3): Permgen space
- OutOfMemoryError系列(4): Metaspace
JVM Java program limits the maximum memory, modify / specify the startup parameters can change this limit. The Java heap memory is divided into a plurality of portions, as shown below:
[Java8 above] and the maximum of these memory pool by -Xmx
and -XX:MaxMetaspaceSize
designation JVM startup parameters. If not explicitly specified, (OS version Version + JVM) and the physical memory size is determined according to the type of platform.
java.lang.OutOfMemoryError: Metaspace information error is expressed by: metadata area (Metaspace) has been filled with
Cause Analysis
If you are a Java older drivers should be familiar with PermGen Java 8 start, but the memory structure has undergone significant changes, no longer used Permgen, but the introduction of a new space:.. Metaspace this change based on various considerations, some The reason listed below:
-
Specific Permgen how much space is difficult to predict. Designated small cause java.lang.OutOfMemoryError: Permgen size error, and set up more wasteful.
-
For GC performance improve, so that the concurrent garbage collection process stage is no longer stalled , further traversal of the metadata for a particular (specific iterators).
-
For G1 garbage collector concurrent class unloading in-depth optimization.
In Java8, before all the content in PermGen, we have moved Metaspace space. For example: class names, field, method, bytecodes, constant pool, the JIT optimized code, and the like.
Metaspace usage number is loaded into the JVM class memory / size. It can be said, java.lang.OutOfMemoryError: Metaspace the main reason for the error is loaded into the memory of too many class or too bulky.
Examples
And PermGen last chapter is similar to the use of Metaspace space, have a great relationship with the number of class JVM loaded. The following is a simple example:
public class Metaspace {
static javassist.ClassPool cp = javassist.ClassPool.getDefault();
public static void main(String[] args) throws Exception{ for (int i = 0; ; i++) { Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass(); } } }
It can be seen using javassist tool generates a class library that is very simple. In a for loop, a lot of dynamically generated class, the class ultimately will be loaded into the Metaspace.
The implementation of this code, as more and more generated class, will eventually occupy Metaspace space, throw java.lang.OutOfMemoryError: Metaspace . On Mac OS X, under Java 1.8.0_05 environment, if you set the start parameters -XX: MaxMetaspaceSize = 64M , loaded after about 70,000 class JVM will hang.
solution
If you throw the Metaspace related OutOfMemoryError, the first solution is to increase the size of Metaspace using startup parameters such as the following:
-XX:MaxMetaspaceSize=512m
Here Metaspace the maximum is set to 512MB, if not used, it will not throw OutOfMemoryError .
There is a seemingly simple solution is to remove the direct Metaspace size limit. Note, however, does not limit Metaspace memory size, if physical memory, may cause memory swapping (swapping), a serious drag on system performance. In addition, it may also cause native memory allocation failures and other issues.
In modern application cluster, would rather let the application node hang up, do not want their slow response.
If you do not receive a warning, you can act like an ostrich, the java.lang.OutOfMemoryError: Metaspace error messages hidden. But this does not really solve the problem, only a matter of time to postpone the outbreak. If indeed there is a memory leak, please refer to the previous article, seriously looking for solutions.
Original link: https://plumbr.eu/outofmemoryerror/permgen-space
Translation Date: September 19, 2017
Translators: anchor: http://blog.csdn.net/renfufei