In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article shares with you the content of an example analysis of a memory overflow in a Java8 virtual machine. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
Introduction to memory overflow of Java8 Virtual Machine (JVM)
I believe that many middle and advanced JAVA students will often encounter an interview question during the interview.
How do you tune and troubleshoot JVM positioning problems at work?
In fact, if the number of users is small, and your code is normal, unless there are very few problems related to JVM at work, even if they are encountered by some big cattle of the company, how can we accumulate experience in this area? Next, let's take you to practice the tuning of JVM.
Note that what we usually call JVM tuning generally refers to Java heap and Java virtual machine stack parameter tuning.
Java heap overflow
First, let's take a code example. Note that the author is using the IDEA tool. You need to configure VM options as-Xms20m-Xmx20m-XX:+HeapDumpOnOutOfMemoryError. If Baidu is not clear, how to configure the JVM running parameters of idea.
Package com.example.demo.jvm;import java.util.ArrayList;import java.util.List;/** * @ Author: Wang Chong * @ Date: 2019-9-22 9:37 * @ Version: V1.0 * / public class HeapOutMemoryTest {static class ChongGuo {} public static void main (String [] args) {List chongGuos = new ArrayList (); while (true) {chongGuos.add (new ChongGuo ());}
The running results are as follows:
Java.lang.OutOfMemoryError: Java heap spaceDumping heap to java_pid9352.hprof... Heap dump file created [28701160 bytes in 0.122 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf (Arrays.java:3210) at java.util.Arrays.copyOf (Arrays.java:3181) at java.util.ArrayList.grow (ArrayList.java:261) at java.util.ArrayList.ensureExplicitCapacity (ArrayList.java:235) at java.util .ArrayList.accounreCapacityInternal (ArrayList.java:227) at java.util.ArrayList.add (ArrayList.java:458) at com.example.demo.jvm.HeapOutMemoryTest.main (HeapOutMemoryTest.java:18) Disconnected from the target VM Address: '127.0.0.1 socket' 54599, transport:
You can see the error of java.lang.OutOfMemoryError: Java heap space in the console. Why? first, explain the above running parameters.
-Xms20m-Xmx20m-XX:+HeapDumpOnOutOfMemoryError
-Xms20m: set the minimum memory of JVM to 20m. This value can be set to the same as-Xmx to prevent JVM from reallocating memory after each garbage collection
-Xmx20m: set the maximum available memory of JVM to 20m
-XX:+HeapDumpOnOutOfMemoryError means that when OOM occurs in JVM, the DUMP file is automatically generated.
Let's analyze the cause of the error, analyze it with JProfiler, and open the dump file named java_pid9352.hprof that we just generated. You can see that you can basically determine which class has a problem based on (InstanceXcount and Size). In the above example, the size of the instance ChongGuo has exceeded 12m, but not more than 20m, so the new problem comes again? Why would a heap memory overflow be reported when it is less than 20m?
The answer is that Metaspace, or meta-memory space, is also included in heap memory in JDK8, which is in JDK7 and its previous JDK version numbers before metaspace appeared in JDK1.7. Heap memory is usually divided into three areas: Nursery memory (young generation), long-term memory (old generation), and permanent memory (Permanent Generation for VM Matedata), as shown in the following figure
The top layer is the younger generation. After an object is created, it is first placed in the Eden memory of the younger generation. Assuming that the survival period exceeds two Survivor, it will be transferred to long-term memory (Old Generation) to store the object's methods, variables and other metadata information. By assuming that there is not enough permanent memory. We get errors such as the following: java.lang.OutOfMemoryError: PermGen
In JDK8, the situation has obviously changed, that is, under normal circumstances, you will not get this error, the reason.
It is in JDK8 that the persistent memory in metadata is moved from heap memory to local memory (native memory)
The JVM heap memory structure in JDK8 becomes, for example, the following
If I start the VM parameter and add:-XX:MaxMetaspaceSize=1m, rerun the above program
Connected to the target VM, address: '127.0.0.1 main 56433, transport:' socket'java.lang.OutOfMemoryError: MetaspaceDumping heap to java_pid9232.hprof... Heap dump file created [1604635 bytes in 0.024 secs] FATAL ERROR in native method: processing of-javaagent failedException in thread "main" Disconnected from the target VM, address: '127.0.0.1 main 56433, transport:' socket'Process finished with exit code 1
You can find that the error message has become java.lang.OutOfMemoryError: Metaspace, indicating that there is not enough meta-space, so I changed it to about 4m to meet the startup conditions.
Virtual machine stack and local method stack overflow
Two exceptions are described in the Java virtual machine specification:
If the stack depth requested by the thread is greater than the maximum allowed by the virtual machine, a StackOverflowError exception will be thrown
If the virtual machine cannot apply for enough memory space in the extension stack, an OutOfMemoryError exception is thrown
StackOverflowError is easy to test. The test code is as follows:
Package com.example.demo.jvm;/** * @ Author: Wang Chong * @ Date: 2019-9-22 19:09 * @ Version: V1.0 * / public class StackOverflowTest {/ * * stack size * / private int stackLength = 1; / * * Recursive stack * / public void stackLeak () {stackLength++; stackLeak () } public static void main (String [] args) {StackOverflowTest stackOverflowTest = new StackOverflowTest (); try {stackOverflowTest.stackLeak ();} catch (Throwable e) {System.out.println ("stack length is:" + stackOverflowTest.stackLength); throw e;}
The running results are as follows:
Exception in thread "main" stack length is: 20739java.lang.StackOverflowError at com.example.demo.jvm.StackOverflowTest.stackLeak (StackOverflowTest.java:20) at com.example.demo.jvm.StackOverflowTest.stackLeak (StackOverflowTest.java:20)
When the VM parameter-Xss parameter is not set, the thread's memory supports a stack depth of 20739. The test result is related to the machine's memory size, but how to test the second point above? Normally, if it is single-threaded, it is difficult to test for memory leaks, so what about multiple threads? Let's take a look at the following test code:
Package com.example.demo.jvm;/** * @ Author: Wang Chong * @ Date: 2019-9-22 19:09 * @ Version: V1.0 * / public class StackOOMTest implements Runnable {/ * * stack size * / private int stackLength = 1; / * * Recursive stack * / public void stackLeak () {stackLength++; stackLeak () } public static void main (String [] args) {while (true) {StackOOMTest stackOverflowTest = new StackOOMTest (); new Thread (stackOverflowTest) .start ();} @ Override public void run () {stackLeak ();}}
If the system does not fake death, Exception in thread "main" java.lang.OutOfMemoryError:unable to create new native thread will appear.
Run time pool overflow
Character constant pool overflow, which is also a heap overflow in JAVA8. The test code is as follows:
Package com.example.demo.jvm;import java.util.ArrayList;import java.util.List;/** * @ Author: Wang Chong * @ Date: 2019-9-22 19:44 * @ Version: V1.0 * / public class RuntimePoolOOMTest {public static void main (String [] args) {List list = new ArrayList (); int I = 0; while (true) {list.add (String.valueOf (I). Intern ()) }}}
The results are as follows:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf (Arrays.java:3210) at java.util.Arrays.copyOf (Arrays.java:3181) at java.util.ArrayList.grow (ArrayList.java:261) at java.util.ArrayList.ensureExplicitCapacity (ArrayList.java:235) at java.util.ArrayList.ensureCapacityInternal (ArrayList.java:227) at java.util.ArrayList.add (ArrayList.java:458) at com .example.demo.jvm.RuntimePoolOOMTest.main (RuntimePoolOOMTest.java:17) Disconnected from the target VM Address: '127.0.0.1 socket' 50253, transport:'
Proves that the character constant pool has been allocated in the heap in Java8.
Method zone overflow
Before Java7, the method area was located in the PermGen, where the permanent generation and the heap were isolated from each other, and the size of the permanent generation could be set to a fixed value when starting JVM, which was immutable; Java8 still retained the concept of the method area, but implemented it in a different way. Cancel the permanent generation, and the method is stored in the Metaspace, which is still not connected to the heap, but shares physical memory with the heap, which can be logically considered to be in the heap
The test code is as follows. To quickly see the result, add the parameter VM-Xms20m-Xmx20m-XX:+HeapDumpOnOutOfMemoryError-XX:MaxMetaspaceSize=10m:
Package com.example.demo.jvm;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;/** * @ Author: Wang Chong * @ Date: 2019-9-22 19:56 * @ Version: V1.0 * / public class MethodAreaOOMTest {public static void main (String [] args) {while (true) {Enhancer enhancer = new Enhancer (); enhancer.setSuperclass (OOMObject.class) Enhancer.setUseCache (false); enhancer.setCallback ((MethodInterceptor) (o, method, objects, methodProxy)-> methodProxy.invokeSuper (o, objects)); enhancer.create ();} static class OOMObject {}}
The running results are as follows:
Java.lang.OutOfMemoryError: MetaspaceDumping heap to java_pid8816.hprof... Heap dump file created [6445908 bytes in 0.039 secs] Exception in thread "main" org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-- > null at org.springframework.cglib.core.AbstractClassGenerator.generate (AbstractClassGenerator.java:345) at org.springframework.cglib.proxy.Enhancer.generate (Enhancer.java:492) at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get (AbstractClassGenerator.java:114) At org.springframework.cglib.core.AbstractClassGenerator.create (AbstractClassGenerator.java:291) at org.springframework.cglib.proxy.Enhancer.createHelper (Enhancer.java:480) at org.springframework.cglib.proxy.Enhancer.create (Enhancer.java:305) at com.example.demo.jvm.MethodAreaOOMTest.main (MethodAreaOOMTest.java:19) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.GeneratedMethodAccessor1.invoke (Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java: 43) at java.lang.reflect.Method.invoke (Method.java:498) at org.springframework.cglib.core.ReflectUtils.defineClass (ReflectUtils.java:459) at org.springframework.cglib.core.AbstractClassGenerator.generate (AbstractClassGenerator.java:336)... 6 moreCaused by: java.lang.OutOfMemoryError: Metaspace at java.lang.ClassLoader.defineClass1 (Native Method) at java.lang.ClassLoader.defineClass (ClassLoader.java:763)... 11 moreProcess finished with exit code 1
The meta-space memory reports an error, which proves that the overflow of the method area is related to the metaspace.
The summary is as follows:
Normal JVM tuning changes the parameters of heap memory, stack memory and metaspace accordingly.
The metaspace is not in the virtual machine, but uses local memory. Therefore, by default, the size of metaspace is limited by local memory only, but you can specify the size of metaspace with the following parameters:
-XX:MetaspaceSize, the initial space size, which triggers garbage collection to unload types, and GC adjusts the value: if a large amount of space is freed, the value is lowered appropriately; if little space is freed, the value is increased appropriately when the MaxMetaspaceSize is not exceeded.
-XX:MaxMetaspaceSize, the maximum space, there is no limit by default.
The string pool constant pool has only one copy per VM, and the referenced value of the string constant is stored in the heap
Thank you for reading! This is the end of the article on "example analysis of Java8 virtual machine memory overflow". I hope the above content can be helpful to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.