Why does JDK1.8 abandon the permanent generation [one piece is enough]

JDK8-Abandoned PermGen (PermGen) ushered in metaspace (Metaspace)

1. Background

2. Why abandon the permanent generation (PermGen)

3. In-depth understanding of metaspace (Metaspace)

4. Summary

======== Text dividing line=====

1. Background

1.1 Where is the permanent generation (PermGen)?

According to the hotspot jvm structure is as follows (virtual machine stack and local method stack are combined):

The above picture is quoted from the network, but there is a problem: both the method area and the heap heap are memory areas shared by threads.

About method area and permanent generation:

In HotSpot JVM, the permanent generation discussed this time is the method area in the figure above (called method area in the JVM specification). The "Java Virtual Machine Specification" only stipulates the concept of method area and its function, but does not stipulate how to implement it. There is no permanent generation on other JVMs.
 

1.2 Obsolescence of JDK8 permanent generation

JDK8 permanent generation changes are as follows:

1. The new generation: Eden+From Survivor+To Survivor

2. Old age: OldGen

3. Permanent generation (implementation of method area): PermGen----->Replace with Metaspace (in local memory)

 

 2. Why abandon the permanent generation (PermGen)

 2.1 Official instructions

Refer to JEP122: http://openjdk.java.net/jeps/122, the original text is intercepted:

Motivation

This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.

 That is: the removal of the permanent generation is an effort to integrate HotSpot JVM and JRockit VM, because JRockit does not have a permanent generation, and there is no need to configure a permanent generation.

 2.2 Prone to problems in actual use

Because the permanent generation memory is often insufficient or memory leaks occur, the exception java.lang.OutOfMemoryError: PermGen

3. Deep understanding of Metaspace

3.1 Memory size of meta space

Metaspace is the implementation of the method area in HotSpot jvm. The method area is mainly used to store class information, constant pools, method data, method codes, etc. The method area is logically part of the heap, but to distinguish it from the heap, it is usually called "non-heap".

The nature of the metaspace is similar to that of the permanent generation, and both are the realization of the method area in the JVM specification. However , the biggest difference between metaspace and permanent generation is that metaspace is not in the virtual machine, but uses local memory. , In theory, depends on the virtual memory size of the 32-bit/64-bit system. It can be seen that it is not unlimited and requires configuration parameters.

3.2 Common configuration parameters

1.MetaspaceSize

The size of the initialized Metaspace controls the threshold of GC that occurs in the metaspace. After GC, increase or decrease the MetaspaceSize dynamically. By default, this value varies from 12M to 20M depending on the platform. Use the Java  -XX:+PrintFlagsInitial command to view the initialization parameters of the machine

2.MaxMetaspaceSize

Limit the upper limit of Metaspace's growth to prevent Metaspace from using local memory indefinitely due to certain circumstances and affecting other programs. The default value of this parameter on this machine is 4294967295B (approximately 4096MB).

3.MinMetaspaceFreeRatio

After Metaspace GC is performed, the current free space ratio of Metaspace will be calculated. If the free space ratio is less than this parameter (that is, the actual non-idle ratio 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 result in slow growth of Metaspace, and the use of Metaspace will gradually become saturated, which may affect subsequent class loading. A too large value will cause Metaspace to grow too fast and waste memory.

4.MaxMetasaceFreeRatio

After Metaspace GC is performed, 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 part of the Metaspace space. The default value is 70, which is 70%.

5.MaxMetaspaceExpansion

Maximum amplitude when Metaspace grows. The default value of this parameter on this machine is 5452592B (about 5MB).

6.MinMetaspaceExpansion

The minimum amplitude when Metaspace grows. The default value of this parameter on this machine is 340784B (about 330KB).

3.3 Test and track the size of the meta space

 3.3.1. Test string constants

import java.util.ArrayList;
import java.util.List;

public class StringTest {
    static String  base = "string";

    public static void main(String[] args) {

        List<String> list = new ArrayList<String>();
        for (int i=0;i< Integer.MAX_VALUE;i++){
            String str = base + base;
            base = str;
            list.add(str.intern());
        }
    }
}

 

 Since the maximum memory is set to 20M, it will overflow soon, as shown in the following figure:

 Visible in jdk8:

1. The string constant is transferred from the permanent generation to the heap.

2. The persistent generation no longer exists, and the PermSize MaxPermSize parameter has been removed. (See the last two lines in the picture)

3.3.2. Test meta space overflow

According to the definition, we test the metaspace overflow by loading the class, the code is as follows:

1 package jdk8; 
 2 
 3 import java.io.File; 
 4 import java.lang.management.ClassLoadingMXBean; 
 5 import java.lang.management.ManagementFactory; 
 6 import java.net.URL; 
 7 import java.net.URLClassLoader; 
 8 import java.util.ArrayList; 
 9 import java.util.List; 
10 
11 /** 
12 * 
13 * @ClassName:OOMTest 
14 * @Description: Simulate class loading overflow (metaspace oom) 
15 * @author diandian.zhang 
16 * @date 9:45:40 AM, April 27, 2017 
17 */ 
18 public class OOMTest {   
19 public static void main(String[] args) {   
20 try {   
21 //Prepare url  
22 URL url = new File("D:/58workplace/11study/src/main/java/jdk8").toURI().toURL();   
23 URL[] urls = {url};   
24 //Get relevant type loading The JMX interface   
25 ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();   
26 //Used to cache class loaders   
27 List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();   
28 while (true) {   
29 //Load types and cache Class Loader instance   
30 ClassLoader classLoader = new URLClassLoader(urls);   
31 classLoaders.add(classLoader);   
32 classLoader.loadClass("ClassA");   
33 //Display quantity information (the number of types that have been loaded in total, which are currently valid Number of types, the number of types that have been uninstalled)  
34                 System.out.println("total: " + loadingBean.getTotalLoadedClassCount());  
35                 System.out.println("active: " + loadingBean.getLoadedClassCount());  
36                 System.out.println("unloaded: " + loadingBean.getUnloadedClassCount());  
37             }  
38         } catch (Exception e) {  
39             e.printStackTrace();  
40         }  
41     }  
42 }  

In order to quickly overflow, set the parameters: -XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=80m, the running results are as follows:

 

 The above figure confirms that the class loading (the function of the method area) in our JDK8 is no longer in the permanent PerGem, but in Metaspace. It can be seen with JVisualVM, which is more intuitive.

 Four, summary

This article explains the origin and essence of Metaspace, common configurations, and monitoring and testing. The size of the meta-space changes dynamically, but it is not infinite. It is best to keep an eye on the size so as not to affect the server memory.

Guess you like

Origin blog.csdn.net/sjmz30071360/article/details/89456177