This article has been transferred from the Internet

This series of articles will be organized into my GitHub repository for the Java Interview Guide. Check out my repository for more highlights

https://github.com/h2pl/Java-Tutorial

If you like, please click Star

Articles will be synced to my personal blog:

www.how2playlife.com

WeChat public is this article number “Java technology river’s lake” of the deep understanding of the JVM virtual machine, one of the article, this part from the network, in order to put this article speaks with clarity theme, also integrates a lot I think good technology content, reference some good blog posts, if there are any copyright infringement, please contact the author.

This series of posts will tell you how from introductory to advanced, step by step to learn basic knowledge of the JVM, and fit for the JVM tuning of actual combat, the JVM is each Java engineer must study and understand the knowledge, you must grasp the implementation principles, to more fully understand the Java technology system, form their own knowledge framework.

In order to better summarize and test your learning results, this series of articles will also provide interview questions and reference answers for each point.

If you have any suggestions or questions about this series of articles, you can also contact the author on the public account “Java Technology Jianghu”. You are welcome to participate in the creation and revision of this series of blog posts.

preface

All Java developers are likely to encounter this confusion? How much space should I set for heap memory? What part of the runtime data does an OutOfMemoryError exception involve? How to solve it?

In fact, if you often solve server performance problems, these problems will become very common. Understanding JVM memory is also a way to quickly understand which area of memory is failing when server performance problems occur, so that you can quickly resolve production failures.

Let’s take a look at a diagram that clearly illustrates the layout of the JVM memory structure.

The JVM memory structure has three main blocks: heap memory, method area, and stack. Heap memory is the largest chunk of the JVM, consisting of the young generation and the old generation. The young generation memory is divided into three parts: Eden space, From Survivor space, and To Survivor space. By default, the young generation is allocated in a 8:1:1 ratio.

The method area stores class information, constants, static variables, and other data. It is shared by threads. To distinguish it from the Java Heap, the method area is also nicknamed non-heap. The stack is divided into Java virtual machine stack and local method stack mainly used for method execution.

How to control the memory size of each region with parameters in a diagram

Control parameters

  • -Xms Sets the minimum size of the heap.
  • -Xmx Sets the maximum size of the heap.
  • -xx :NewSize Sets the minimum space size of the new generation.
  • -xx :MaxNewSize Sets the maximum space size of the new generation.
  • -xx :PermSize Sets the minimum space size of the permanent generation.
  • -xx :MaxPermSize Sets the maximum space of the permanent generation.
  • -Xss sets the stack size for each thread.

There is no direct setting of the old age parameters, but you can set the heap size and the new generation space size two parameters to indirectly control.

Old age space size = heap space size – young generation large space size

Look again at the relationship between the JVM and system calls from a higher dimension

Method areas and pairs are memory areas shared by all threads; The Java stack, native method stack, and programmer counter are areas of memory that are run private to the thread.

Let’s go into more detail about what each region does

Java Heap

For most applications, the Java Heap is the largest chunk of memory managed by the Java virtual machine. The Java heap is an area of memory that is shared by all threads and is created when the virtual machine is started. The sole purpose of this memory area is to hold object instances, and almost all object instances are allocated memory here.

The Java heap is the primary area managed by the garbage collector and is often referred to as the “GC heap”. From the point of view of memory collection, the Java heap can be subdivided into: new generation and old generation; More detailed are Eden space, From Survivor space, To Survivor space, etc.

According to the Java Virtual Machine specification, the Java heap can be in a physically discontinuous memory space, as long as it is logically contiguous, like our disk space. When implemented, it can be either fixed size or extensible, but most current virtual machines are implemented as extensible (controlled by -xmx and -xMS).

OutOfMemoryError is thrown if there is no memory in the heap to complete the instance allocation and the heap can no longer be extended.

Method Area

The Method Area, like the Java heap, is an Area of memory shared by threads that stores information about classes loaded by the virtual machine, constants, static variables, code compiled by the just-in-time compiler, and so on. Although the Java Virtual Machine specification describes the method area as a logical part of the Heap, it has an alias called non-heap, which is supposed to distinguish it from the Java Heap.

For developers who are used to developing and deploying applications on the HotSpot VIRTUAL machine, many prefer to refer to the method area as “Permanent Generation”, which is essentially not equivalent, simply because the HotSpot Virtual machine design team chose to extend GC Generation collection to the method area. Or to implement method sections using persistent generation.

The Java Virtual Machine specification is very relaxed about this area, in addition to the fact that, like the Java heap, it does not require contiguous memory and has the option of either fixed size or scalability, and optionally does not implement garbage collection. Garbage collection is relatively rare in this area, but it is not as “permanent” as the name of the permanent generation that data enters the method area. The target of memory reclamation in this area is mainly for constant pool reclamation and type unloading. Generally speaking, the “performance” of the reclamation in this area is not satisfactory, especially for type unloading, but the reclamation in this part of the area is indeed necessary.

According to the Java Virtual Machine specification, OutOfMemoryError is thrown when the method area cannot meet memory allocation requirements.

Method regions are sometimes called PermGen.

All objects are stored in heap memory for the entire runtime after instantiation. The heap memory is divided into different parts: Eden, Survivor, and Old Generation Space.

Methods are executed with threads. Local variables and references of primitive types are stored in the thread stack. Objects that reference associations, such as strings, are stored in the heap. To understand the above statement, let’s look at an example:

import java.text.SimpleDateFormat; import java.util.Date; import org.apache.log4j.Logger; public class HelloWorld { private static Logger LOGGER = Logger.getLogger(HelloWorld.class.getName()); public void sayHello(String message) { SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.YYYY"); String today = formatter.format(new Date()); LOGGER.info(today + ": " + message); }}

The data of this program is stored in memory as follows:

The JConsole tool allows you to view information about running Java programs such as Eclipse: heap memory allocation, number of threads, and number of classes loaded;

Program Counter Register

The Program Counter Register is a small memory space that acts as a line number indicator of the bytecode being executed by the current thread. In the concept of virtual machine model (just the conceptual model, all kinds of virtual machine may be through some of the more efficient way to achieve), bytecode interpreter to work is by changing the counter value to select a need to be performed under the bytecode instruction, branches, loops, jumps, exception handling, thread to restore the basic function such as all need to rely on the counter.

Because multithreading in the Java VIRTUAL machine is implemented by the way threads alternate and allocate processor execution time, at any given moment, one processor (or kernel for multi-core processors) will execute instructions in only one thread. Therefore, in order to restore the thread to the correct execution position after switching, each thread needs to have an independent program counter. Counters between threads do not affect each other and are stored independently. We call this kind of memory area “thread private” memory.

If the thread is executing a Java method, this counter records the address of the virtual machine bytecode instruction being executed. If the Natvie method is being executed, this counter value is null (Undefined).

This memory region is the only one where the Java Virtual Machine specification does not specify any OutOfMemoryError cases.

JVM Stacks

Like program counters, the Java Virtual Machine Stack is thread-private and has the same lifetime as a thread. Virtual machine Stack describes the memory model of Java method execution: each method execution creates a Stack Frame to store information such as local variation table, operation Stack, dynamic link, method exit, etc. Each method is called until the execution is complete, corresponding to the process of a stack frame in the virtual machine stack from the stack to the stack.

The local variable table stores various basic data types known at compile time (Boolean, byte, CHAR, short, int, float, long, double), object references (reference type, which is not equivalent to the object itself, depending on the implementation of different virtual machines. It may be a reference pointer to the object’s starting address, a handle to the object or some other location associated with the object, and the returnAddress type (which points to the address of a bytecode instruction).

64-bit long and double data occupy two local variable slots, and the rest occupy only one. The memory space required for the local variable table is allocated at compile time. When entering a method, how much local variable space the method needs to allocate in the frame is completely determined, and the size of the local variable table does not change during the method run.

In the Java Virtual Machine specification, two exceptions are specified for this area: a StackOverflowError is thrown if the stack depth of a thread request is greater than the depth allowed by the virtual machine; If the virtual stack can scale dynamically (and most Java virtual machines currently do, although the Java Virtual Machine specification also allows fixed-length virtual stacks), an OutOfMemoryError will be thrown when sufficient memory cannot be allocated while scaling.

Native Method Stacks

The Native Method stack is similar to the virtual machine stack, except that the virtual machine stack performs Java methods (i.e. bytecodes) for the virtual machine, whereas the Native Method stack services the Native methods used by the virtual machine. The virtual machine specification does not mandate the language, usage, or data structure of methods in the local method stack, so specific virtual machines are free to implement it. There are even virtual machines (such as the Sun HotSpot VIRTUAL machine) that simply merge the local method stack with the virtual machine stack. Like the virtual stack, the local method stack area throws StackOverflowError and OutOfMemoryError exceptions.

Where is the OutOfMemoryError

A clear understanding of the memory structure also helps to understand the different OutOfMemoryErrors:

The Exception in the thread "main" : Java. Lang. OutOfMemoryError: Java heap space

Cause: Objects cannot be allocated to heap memory

The Exception in the thread "main" : Java. Lang. OutOfMemoryError: PermGen space

Cause: A class or method cannot be loaded into a persistent generation. It can occur when an application loads many classes, such as libraries that reference many third parties.

The Exception in the thread "main" : Java. Lang. OutOfMemoryError: Requested array size exceeds limit VM

Cause: The array created is larger than the heap memory

The Exception in the thread "main" : Java. Lang. OutOfMemoryError: request bytes for the Out of swap space?

Cause: Local allocation failed. The JNI, local library, or Java virtual machine allocates memory space from the local heap.

The Exception in the thread "main" : Java. Lang. OutOfMemoryError: (Native method)

Cause: The same local method failed to allocate memory, only JNI or local method or Java virtual machine discovered

JDK8- PermGen for Metaspace

1. The background

2. Why do you discard PermGen?

3. Deep understanding of Metaspace

4. To summarize

======== Body split line =====

The background,

1.1 Where is PermGen?

According to the hotspot JVM structure, the virtual machine stack and the local method stack are combined:

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

About method sections and permanent generation:

In HotSpot JVM, the permanent generation for this discussion is the method area shown above (called the method area in the JVM specification). The Java Virtual Machine Specification defines the concept of a method area and what it does, not how to implement it. There are no permanent generations on other JVMS.

1.2 JDK8 Permanent Generation Abandonment

The changes of JDK8 permanent generation are shown as follows:

1. New generation: Eden+From Survivor+To Survivor

2. Age: 45

3. Permanent generation (method area implementation) : PermGen—–> replace Metaspace(in local memory)

2. Why to discard PermGen

2.1 Official Instructions

The original reference JEP122:http://openjdk.java.net/jeps/122, intercept:

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, removing the persistent generation is an effort to merge HotSpot JVM with JRockit VM, as JRockit does not have persistent generations and does not need to be configured.

2.2 Problems may arise in practical use

Due to the permanent generation memory often enough or memory leaks occur, when abnormal Java. Lang. OutOfMemoryError: PermGen

In fact, in JDK7, the content of permanent generation has been gradually moved to other areas, such as moving to native area, moving to heap area, etc. In JDK8, it abolished permanent generation and used metadata.

3. Deep Understanding of Metaspace

3.1 Memory size of the meta-space

The meta-space is the implementation of the method area in HotSpot JVM. The method area is used to store class information, constant pools, method data, method code, etc. The method area is logically part of the heap, but is often referred to as “non-heap” to distinguish it from the heap.

Similar in nature to permanent generations, meta-spaces are implementations of method areas in the JVM specification. However, the biggest difference between a meta-space and a permanent generation is that the meta-space is not in the virtual machine, but uses local memory. , theoretically depends on how much memory a 32-bit / 64-bit system can virtualize. Visibility is not unlimited, you need to configure parameters.

3.2 Common Configuration Parameters

1.MetaspaceSize

The size of the initialized Metaspace, which controls the threshold at which GC occurs in the meta-space. Dynamically increase or decrease MetaspaceSize after GC. By default, this value varies from 12M to 20M depending on the platform. Use the Java -xx :+PrintFlagsInitial command to view the native initialization parameters

2.MaxMetaspaceSize

Limit the growth of Metaspace to prevent situations that cause Metaspace to use local memory indefinitely and affect other programs. The default value of this parameter is 4294967295B (about 4096MB).

3.MinMetaspaceFreeRatio

After the Metaspace GC is performed, the current Metaspace free space ratio is calculated. If the free ratio is less than this parameter (i.e. the actual non-free ratio is too large and the memory is insufficient), the virtual machine will increase the Metaspace size. The default value is 40, which is 40%. If this parameter is set, the growth rate of Metaspace can be controlled. If the value is too small, the growth rate of Metaspace will be slow, and the use of Metaspace will gradually become saturated, which may affect the class loading in the future. Too large a value will cause Metaspace to grow too fast, wasting memory.

4.MaxMetasaceFreeRatio

After the Metaspace GC is performed, the current Metaspace free space ratio is calculated. If the free ratio is greater than this parameter, the virtual machine frees part of the Metaspace space. The default value is 70, which is 70%.

5.MaxMetaspaceExpansion

The maximum amount of Metaspace growth. The default value of this parameter is 5452592B (about 5MB) on the local machine.

6.MinMetaspaceExpansion

The minimum amount of Metaspace growth. On the local machine, the default value of this parameter is 340784B.

3.3 Test and track the size of the meta-space

3.3.1. Test string constants

1 public class StringOomMock {2 static String base = "string"; 3

4 public static void main(String[] args) {5 List list = new ArrayList(); 6 for (int i=0; i< Integer.MAX_VALUE; i++){7 String str = base + base; 8 base = str; 9 list.add(str.intern()); 11 10}}} 12

In Eclipse, select the class — “Run Configuration –> Java Application –” with the following new parameters:

As the maximum memory was set at 20M, it soon overflowed, as shown below:

As can be seen in jdK8:

1. String constants are moved from the permanent generation to the heap.

2. The persistent generation does not exist and the PermSize MaxPermSize parameter has been removed. (Look at the last two lines.)

3.3.2. Test for metaspace overflow

By definition, we test for a metaspace overflow by loading a class as follows:

1 package jdk8; 23 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; 1011 /**12 *13 * @className :OOMTest14 * @description: Simulation class loading overflow (oom) 15 * @author diandian.zhang16 * @date 17 */18 public class OOMTest {17 */18 public class OOMTest {

19 public static void main(String[] args) {

20 try {

21 // Prepare the URL

22 URL url = new File("D:/58workplace/11study/src/main/java/jdk8").toURI().toURL();

23 URL[] urls = {url};

24 // Get the JMX interface for type loading

25 ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();

26 // Used for caching class loaders

27 List classLoaders = new ArrayList();

28 while (true) {

29 // Load the type and cache the class loader instance

30 ClassLoader classLoader = new URLClassLoader(urls);

31 classLoaders.add(classLoader);

32 classLoader.loadClass("ClassA");

33 // Display quantity information (total number of loaded types, number of currently valid types, number of unloaded types)

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}

-xx :MetaspaceSize=8m -xx :MaxMetaspaceSize=80m. The result is as follows:

The figure above confirms that our JDK8 class loading (method area functionality) is no longer in PerGem, but in Metaspace. It can be seen with JVisualVM to make it more intuitive.

Four,

This article explains the origin and nature of Metaspace, common configurations, and monitoring tests. The size of the meta-space changes dynamically, but it is not infinite, and it is best to keep an eye on the size from time to time to avoid affecting server memory.

Refer to the article

https://blog.csdn.net/android_hl/article/details/53228348