Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand JVM memory area and memory overflow Analysis

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article is about how to understand the JVM memory area and memory overflow analysis, the editor thinks it is very practical, so I share it with you to learn. I hope you can get something after reading this article.

Preface

Under the control of JVM, Java programmers no longer need to manage memory allocation and release, which is completely different from the world of C and C++. Therefore, with the help of JVM, Java programmers rarely pay attention to memory leaks and memory spills. However, once this happens in JVM, it is difficult to locate and solve the problem if you are not clear about the memory management mechanism of JVM memory.

1. JVM memory area

When the Java virtual machine is running, it divides the memory space into several areas. According to the "Java virtual machine specification (Java SE version 7)", the memory area managed by the Java virtual machine is divided into the following parts: method area, heap memory, virtual machine stack, local method stack, program counter.

1. Method area

The method area is mainly used to store the class information, constants, static variables loaded by the virtual machine, and the compiled code of the compiler. Before jdk1.7 and before, the method area was a "logical part" of the heap (a contiguous heap space), but to distinguish it from the heap, the method area was also called "non-heap", and some people used "permanent generation" (the implementation of the HotSpot method area) to represent the method area.

Since jdk1.7 has started to prepare for the "de-permanent generation" plan, the HotSpot of jdk1.7 has moved the static variables and string constant pool originally placed in the method area to heap memory (constant pool in addition to string constant pool and class constant pool, etc.). Here, only the string constant pool is moved to heap memory. In jdk1.8, the method area no longer exists, and the class information and compiled code data stored in the original method area have been moved to the MetaSpace, which is not on the heap memory, but directly occupied local memory (NativeMemory). According to the information on the Internet and my own understanding, I draw a picture of the changes of the Chinese legal area in jdk1.3~1.6, jdk1.7 and jdk1.8 as follows (if there is anything unreasonable, I hope the reader will point out):

The reasons for going to the permanent generation are:

(1) the string is in permanent generation, which is prone to performance problems and memory overflow.

(2) it is difficult to determine the size of classes and methods, so it is difficult to specify the size of permanent generation. if it is too small, it is easy to cause permanent generation overflow, and if it is too large, it is easy to lead to old age spillover.

(3) permanent generation will bring unnecessary complexity to GC, and the recovery efficiency is low.

2. Heap memory

Heap memory is mainly used to store objects and arrays. It is the largest area of memory managed by JVM. Heap memory and method area are shared by all threads and created when the virtual machine starts. On the level of garbage collection, because the current collectors basically use generation-by-generation collection algorithm, the heap can be divided into YoungGeneration and OldGeneration, and the Cenozoic can be divided into Eden, From Survivor and To Survivor.

3. Program counter

The program counter is a very small memory space, which can be regarded as the line number indicator of the current thread executing bytecode. Each thread has an independent program counter, so the program counter is a private space of the thread. In addition, the program counter is the only area specified by the Java virtual machine that will not have a memory overflow.

4. Virtual machine stack

The virtual machine stack is also a private memory space for each thread, which describes the memory model of the method, as shown in the following figure:

The virtual machine assigns a virtual machine stack to each thread, and there are several stack frames in each virtual machine stack, in which local variable tables, Operand stacks, dynamic links, return addresses and so on are stored. A stack frame corresponds to a method in Java code. When a thread executes a method, it means that the stack frame corresponding to this method has entered the virtual machine stack and is at the top of the stack. Each Java method corresponds to a stack frame process from being called to the end of execution.

5. Local method stack

The difference between the local method stack and the virtual machine stack is that the virtual machine stack executes the Java method, the local method stack executes the local method (Native Method), and the others are basically the same. The local method stack and the virtual machine stack are directly combined into one in HotSpot.

6. Metaspace

As mentioned above, in jdk1.8, there is no permanent generation (method zone), and the space that replaces it is called "meta-space". Similar to the permanent generation, it is the implementation of the JVM specification of the other legal area, but the meta-space is not in the virtual machine, but uses local memory. The size of meta-space is limited by local memory, but you can specify the size of meta-space through-XX:MetaspaceSize and-XX:MaxMetaspaceSize.

2. JVM memory overflow

1. Heap memory overflow

Objects, arrays, etc., are mainly stored in heap memory. As long as these objects are constantly created and there is a reachable path between GC Roots and objects to avoid garbage collection mechanism to clear these objects, when these objects occupy more space than the maximum heap capacity, an OutOfMemoryError exception will occur. Examples of heap memory exceptions are as follows:

/ * set maximum and minimum heap:-when Xms20m-Xmx20m* runs, it constantly creates instance objects of OOMObject class in the heap, and before the end of while execution, there is a reachable path between GC Roots (oomObjectList in the code) and objects (each OOMObject object), so the garbage collector cannot reclaim them, resulting in memory overflow. * / public class HeapOOM {static class OOMObject {} public static void main (String [] args) {List oomObjectList = new ArrayList (); while (true) {oomObjectList.add (new OOMObject ());}

An exception is reported after running, which can be seen in the stack information:

Java.lang.OutOfMemoryError: information from Java heap space indicating that a memory overflow exception occurred in the heap memory space.

The newly generated objects are initially allocated to the new generation, and a Minor GC will be carried out after the new generation is full. If there is not enough space after Minor GC, the object and the objects that meet the requirements of the new generation will be put into the old era, and Full GC will be carried out when the space is insufficient. Later, if there is not enough space to store the new object, an OutOfMemoryError exception will be thrown.

Common reasons: too much data loaded in memory, such as fetching too much data from the database at one time; too many references to objects in the collection and not emptied after use; there is an endless loop or loop in the code that produces too many duplicate objects; unreasonable heap memory allocation; network connection problems, database problems, etc.

2. Virtual machine stack / local method stack overflow

(1) StackOverflowError: when the depth of the stack requested by a thread is greater than the maximum depth allowed by the virtual machine, StackOverflowError is thrown. It simply means that when there are too many stack frames in the virtual machine stack (too many methods are nested by a thread), a StackOverflowError exception will be thrown.

The most common scenario is an infinite recursive call to a method, as follows:

/ * set the stack size of each thread:-when Xss256k* is running, the doSomething () method is called constantly, and the main thread keeps creating stack frames and merging them into the stack, resulting in a deeper and deeper stack and eventually a stack overflow. * / public class StackSOF {private int stackLength=1; public void doSomething () {stackLength++; doSomething ();} public static void main (String [] args) {StackSOF stackSOF=new StackSOF (); try {stackSOF.doSomething ();} catch (Throwable e) {/ / Note that Throwable System.out.println ("stack depth:" + stackSOF.stackLength) is captured. Throw e;}

Thrown after the above code is executed:

Exception of Exception in thread "Thread-0" java.lang.StackOverflowError.

(2) OutOfMemoryError: if the virtual machine cannot apply for enough memory space when expanding the stack, OutOfMemoryError is thrown.

We can understand that the space available for stack in a virtual machine ≈ available physical memory-maximum heap memory-maximum method area memory, for example, a machine memory is 4G, systems and other applications occupy 2G, the physical memory available to the virtual machine is 2G, the maximum heap memory is 1G, the maximum method area memory is 512m, then the memory available for the stack is about 512m. If we set the size of each thread stack to 1m, a maximum of 512 threads can be created in the virtual machine. If more than 512 threads are created, there will be no room for the stack, and an OutOfMemoryError exception will be reported.

An example of generating OutOfMemoryError on the stack is as follows:

/ * set the stack size of each thread:-when Xss2m* runs, new threads are created continuously (and each thread continues to execute), each thread is on a stack, and finally there is no extra space to allocate for the new thread, resulting in OutOfMemoryError*/public class StackOOM {private static int threadNum = 0; public void doSomething () {try {Thread.sleep (100000000) } catch (InterruptedException e) {e.printStackTrace ();}} public static void main (String [] args) {final StackOOM stackOOM = new StackOOM (); try {while (true) {threadNum++ Thread thread = new Thread (new Runnable () {@ Override public void run () {stackOOM.doSomething ()}}); thread.start () }} catch (Throwable e) {System.out.println ("current number of active threads:" + threadNum); throw e;}

An exception will be reported after the above code is run

You can see the java.lang.OutOfMemoryError: unable to create new native thread message in the stack information, unable to create a new thread, indicating a memory overflow exception while extending the stack.

Summary: when there are fewer threads, a thread will report a StackOverflow exception if the request depth is too large. To solve this problem, you can appropriately increase the stack depth (increase the stack space size), that is, set the value of-Xss to higher, but in general, it is more likely to have code problems; when the virtual machine generates a thread, you cannot apply for stack space for the thread.

An OutOfMemoryError exception will be reported. To solve this problem, you can appropriately reduce the depth of the stack, that is, set the value of-Xss to a smaller value. If each thread occupies less space, the total space must be able to accommodate more threads. However, the operating system has a limit on the number of threads in a process, and the experience value is about 3000 to 5000.

Before jdk1.5-Xss defaults to 256k JDK 1.5 and then defaults to 1m. This option is quite hard for the system, and should be set up carefully according to the actual situation.

3. Method area overflow

As mentioned earlier, the method area is mainly used to store data such as class information, constants, static variables, and compiled code loaded by the virtual machine, so the reason for the method area overflow is that there is not enough memory to store the data.

Since the string constant pool exists in the method area before jdk1.6, the virtual machine before jdk1.6 can simulate the OutOfMemoryError exception in the method area by constantly generating inconsistent strings (while ensuring a reachable path with GC Roots); but the method area also stores the loaded class information, so the virtual machine based on jdk1.7 can simulate the method area overflow by dynamically creating a large number of classes.

/ * set the maximum and minimum space of the method area:-when XX:PermSize=10m-XX:MaxPermSize=10m* is running, subclasses of JavaMethodAreaOOM are created continuously through cglib, and there is more and more class information in the method area. Finally, no memory that can be allocated for the new class leads to memory overflow * / public class JavaMethodAreaOOM {public static void main (final String [] args) {try {while (true) {Enhancer enhancer=new Enhancer () Enhancer.setSuperclass (JavaMethodAreaOOM.class); enhancer.setUseCache (false); enhancer.setCallback (new MethodInterceptor () {@ Override public Object intercept (Object o, Method method, Object [] objects, MethodProxy methodProxy) throws Throwable {return methodProxy.invokeSuper (opaper objects);}}) Enhancer.create ();}} catch (Throwable t) {t.printStackTrace ();}

After the above code is run, it will report:

Java.lang.OutOfMemoryError: the exception of PermGen space indicates that a memory overflow error occurred in the method area.

4. Native direct memory overflow

Native direct memory (DirectMemory) is not part of the runtime data area of a virtual machine, nor is it a memory area defined in the Java virtual machine specification, but memory overflow exceptions may also occur when NIO-related operations are used in Java (for example, the allocteDirect method of ByteBuffer requests native direct memory).

JVM memory area is divided so that it can manage its own memory more efficiently. When this kind of memory overflow caused by JVM occurs in the program, it needs to be analyzed and handled differently according to different situations.

The above is how to understand the JVM memory area and memory overflow analysis, the editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report