As mentioned in the previous article, the method area stores data such as class information, constants, static variables, and code compiled by the just-in-time compiler that the virtual machine has loaded. At the same time, the runtime constant pool is also part of the method area. However, there are certain differences in the implementation of the method area in different JDK versions.
Let's take a look at the respective implementation methods by comparing the runtime constant pools of JDK 1.6, JDK 1.7, and JDK 1.8.
JDK 1.6
In JDK 1.6 and earlier versions (for HotSpot virtual machine), the constant pool is allocated in the permanent generation.
public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
int i = 0;
while(true)
{
System.out.println(i);
list.add(String.valueOf(i++).intern());
}
}
}
JDK version number:
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
operation result:
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at com.access.RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:14)
It can be seen from the running results that the runtime constant pool overflows. The prompt message following OutOfMemoryError is "PermGen spacer", indicating that the runtime constant pool is part of the method area (permanent generation in the HotSpot virtual machine).
Observe the memory running track of PermGen by using Java VisualVM tool:
As can be seen from the above figure: because the program uses the list to save the string references in the PernGem area, the memory in the PermGen area continues to soar until the OutOfMemoryError exception is thrown.
If the String object is not added to the list:
As can be seen from the above figure: As long as the usage of PermGen approaches or reaches the maximum size, garbage collection in the PermGen area will be triggered.
JDK 1.7
JDK version number:
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
Observe the PernGen memory running trajectory graph by using Java VisualVM tools:
It can be seen from the PernGen running track: PernGen is very stable, indicating that the constant pool is not allocated to the PernGen memory area.
Observe the heap memory running track graph by using Java VisualVM tools:
From the running track of the heap memory, it can be seen that the heap does not increase continuously, and finally an OutOfMemoryError is thrown. From the above figure, we can know that the constant pool allocates storage space on the heap.
operation result:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at com.access.RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:14)
It can be seen from the running results that JDK1.7 moved the constant pool from the permanent generation to the Java heap, so the heap overflow is prompted in the Exception.
JDK 1.8
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 4265607168 (4068.0MB)
NewSize = 89128960 (85.0MB)
MaxNewSize = 1421869056 (1356.0MB)
OldSize = 62914560 (60.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
With the advent of JDK 8, PermGen no longer exists for the JVM. But the metadata of the class is still there, but it is not stored in the contiguous heap space, but moved to the native memory called "Metaspace".
The nature of metaspace is similar to that of permanent generation, both of which implement the method area in the JVM specification, but the biggest difference between metaspace and permanent generation is:Metaspace is not in the virtual machine, but uses local memory. Theoretically, it depends on the virtual memory size of a 32-bit/64-bit system. It can be seen that it is not infinite, and requires configuration parameters.
Now most of the class metadata is allocated in localized memory. By default, class metadata allocation is limited by the available native memory capacity (capacity still depends on whether you are using a 32-bit JVM or 64-bit operating system virtual memory availability. The available memory on my machine is 1082130432 B).
Reasons for transferring metadata information of the class to Metaspace:
- Strings are stored in the permanent generation, which is prone to performance problems and memory overflow.
- PermGen's recovery "scores" in this area are relatively unsatisfactory, especially for types of unloading, where conditions are quite harsh.
Common configuration parameters:
1:MetaspaceSize
Initialize the size of Metaspace and control the threshold of GC in the metaspace. After GC, increase or decrease the MetaspaceSize dynamically. By default, this value is floating from 12M to 20M according to different products. Use the Java -XX:+PrintFlagsInitial command to view the initialization parameters of the machine
2:MaxMetaspaceSize
Restrict the upper limit of Metaspace growth to prevent Metaspace from using local memory indefinitely due to certain circumstances and affecting other programs.
3:MinMetaspaceFreeRatio
After Metaspace GC, the free space ratio of the current Metaspace will be calculated. If the free space ratio is less than this parameter (that is, the actual non-free space is too large and the memory is not enough), then the virtual machine will increase the size of the Metaspace. The default value is 40, which is 40%. Setting this parameter can control the growth rate of Metaspace. Too small a value will cause Metaspace to grow slowly, and the use of Metaspace will gradually become saturated, which may affect subsequent class loading. A too large value will cause the Metaspace to grow too fast and waste memory.
4:MaxMetaspaceFreeRatio
After Metaspace GC, the free space ratio of the current Metaspace will be calculated. If the free space ratio is greater than this parameter, the virtual machine will release some Metaspace parameters. The default value is 70, which is 70%.
5:MaxMetaspaceExpansion
The maximum extent when Metaspace grows.
6:MinMetaspaceExpansion
The minimum amplitude when Metaspace grows.
Select the class setting parameters in eclipse: -Xms20m -Xmx20 -XX:PermSize=8m -XX:MaxPermSize=8M
When running, it will prompt:
ClassA
package com.memory;
public class ClassA {
}
Compile ClassA into a class file and run the following program.
package com.memory;
import java.io.File;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.ManagementFactory;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
public class OOMTest {
public static void main(String[] args) {
try{
//Prepare url
URL url = new File("D:/eclipse/javaEE/WebWorkSpace/ClassProject/src").toURI().toURL();
URL[] urls = {url};
//Get the JMX interface for type loading
ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();
//Used to cache class loader
List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
while(true) {
//Load type and cache class loader instance
ClassLoader classLoader = new URLClassLoader(urls);
classLoaders.add(classLoader);
classLoader.loadClass("com.memory.ClassA");
//Display quantity information (the total number of types loaded, the number of currently valid types, the number of types that have been unloaded)
System.out.println("total: "+ loadingBean.getTotalLoadedClassCount());
System.out.println("active: "+ loadingBean.getLoadedClassCount());
System.out.println("unloaded: "+ loadingBean.getUnloadedClassCount());
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
Runtime parameter settings: -XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=512m -XX:PermSize=8m -XX:MaxPermSize=8M
Trajectory of Metaspace space:
It can be seen from the screenshot of JVisualVM above: When the total number of loaded classes reaches 87386, the Metaspace area will overflow. You can also understand the exhaustion of meta-space memory by observing the trajectory of garbage collection activities. Java program running results:
total: 87416
active: 87416
unloaded: 0
Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.memory.OOMTest.main(OOMTest.java:26)
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=8m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=8M; support was removed in 8.0
JVM memory structure refinement Then look at "Detailed structure of JVM memoryFIG memory structure "on. For more detailed explanations, we refer to this chart to further optimize the adjustm...
Element space difference (MetaSpace) and the permanent generation of (the PermGen) of Dimensional space using local memory, and on behalf of the permanent memory using a jvm Element space (MetaSpace) ...
Foreword The first thing that needs to be clear is that the HotSpot virtual machine we discuss below, and other types of virtual machines, such as JRockit and J9, have no permanent generation concept ...
Article Directory review 1. Metaspace replaces persistent generation 1.1, persistent generation 1.2, why remove the persistent generation 1.3. The status of PermGen space after removing the permanent ...
Transfer from: 1. Metaspace replaces persistent generation 1.1, durable generation The full name of PermGen space is Permanent Generation space, which refers to the permanent storage area of ...
JAva8 memory model - permanent generation (PermGen) and metaspace (Metaspace) First, JVM memory model According to the JVM specification, JVM memory is divided into five parts: virtual machine stack, ...
http://blog.csdn.net/zhyhang/article/details/17246223 As you know,JDK 8 Early AccessThe version is already available for download. This allows developers to experience the new features of Java ...
Reprinted in this article Author:liuxiaopeng blog address: First, JVM memory structure According to the JVM specification, JVM memory is divided into five parts: virtual machine stack, heap, method ar...
One, JVM memory model According to the JVM specification, JVM memory is divided into five parts: virtual machine stack, heap, method area, program counter, and local method stack. 1. Virtual machine s...
Java8 memory model—PermGen and Metaspace To view the original text, click on the portal: Tip: Some changes have been made in this article One, JVM memory model According to the JVM specification...