Java8 Virtual Machine (JVM) memory overflow combat

Foreword

I believe that many JAVA senior students during the interview will often encounter a face questions
how you work in the JVM tuning and troubleshooting localization issues ?

In fact, under the amount if the user is not the case in your code fairly normal circumstances, at work unless a real encounter with the JVM-related problems are few and far between, even if met also by the large number of companies cattle investigation to solve, then how can we accumulate experience in this area do? Here we bring together a pot of red practice tuning the JVM it

Note that we usually say JVM tuning generally refers to the Java heap, Java Virtual Machine stack parameters tuning

Java heap overflow

First to a piece of code examples, note the author uses IDEA tool, need to configure the VM options to -Xms20m -Xmx20m -XX: + HeapDumpOnOutOfMemoryError, if you are unsure of how to configure the JVM Baidu idea of ​​operating parameters

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<ChongGuo> chongGuos = new ArrayList<>();
        while (true) {
            chongGuos.add(new ChongGuo());
        }
    }
}

Results are as follows:

java.lang.OutOfMemoryError: Java heap space
Dumping 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.ensureCapacityInternal(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:54599', transport: 'socket'

You can see the console appear java.lang.OutOfMemoryError: Java heap space error, which is why, first of all to explain the above operating parameters

-Xms20m -Xmx20m -XX: + HeapDumpOnOutOfMemoryError


  • -Xms20m: Set the minimum JVM memory to 20m. This value can be set the same -Xmx, to avoid re-allocating memory garbage collection is completed after each JVM

  • -Xmx20m: Set JVM maximum available memory 20M

  • -XX: + HeapDumpOnOutOfMemoryError indicates when the JVM occurs OOM, automatically generated file DUMP


Here we analyze the cause of the error, with JProfiler analysis, the open dump file named java_pid9352.hprof just generated. Can be seen according to (InstanceXcount and Size) class of objects which can determine the basic problem, in the above example, can be ChongGuo this instance the number of students has exceeded the size of 12M, but no more than 20M, then the new problem again? Why not to 20M heap memory overflow will be reported it ?

The answer is in heap memory JDK8 also includes Metaspace, namely yuan memory space, space appear before the yuan before JDK1.7 JDK7 and in its early JDK version number. Heap memory is usually divided into three memory areas Nursery (young generation), when the memory length (old generation), persistent memory (Permanent Generation for VM Matedata), following FIG.

Among the top layer is the young generation, after an object is created first to be placed in the young generation in Eden in memory, assuming that survival will be transferred to the long memory (Old Generation) in permanent memory after two Super Survivor storing the metadata object methods, variables, and other information. By assuming enough permanent memory. For example we will get the following error: java.lang.OutOfMemoryError: PermGen
and significant changes have taken place in JDK8 the case is under ordinary circumstances you will not get this wrong, the reason
is that JDK8 metadata stored in the permanent memory moved to the local memory (native memory) memory from the heap
in, JDK8 the JVM heap memory structure becomes the following example:

If I start the VM parameters plus: -XX: MaxMetaspaceSize = 1m, re-run the above program,

Connected to the target VM, address: '127.0.0.1:56433', transport: 'socket'
java.lang.OutOfMemoryError: Metaspace
Dumping heap to java_pid9232.hprof ...
Heap dump file created [1604635 bytes in 0.024 secs]
FATAL ERROR in native method: processing of -javaagent failed
Exception in thread "main" Disconnected from the target VM, address: '127.0.0.1:56433', transport: 'socket'

Process finished with exit code 1

Can be found in the error message into a java.lang.OutOfMemoryError: Metaspace , explained yuan is not enough space, I changed to probably start around 4m in order to meet the conditions.

VM stack and native method stacks stack overflow

Java Virtual Machine specification describes two anomalies:

  • If the stack is greater than the depth of the thread requested the maximum depth allowed by the virtual machine will throw an exception StackOverflowError
  • If the virtual machine can not be extended to apply to stack enough memory space, throw an OutOfMemoryError

    StackOverflowError better test, test code as follows:

package com.example.demo.jvm;

/**
 * @Author: Wang Chong
 * @Date: 2019/9/22 19:09
 * @Version: V1.0
 */
public class StackOverflowTest {

    /**
     * 栈大小
     */
    private int stackLength = 1;

    /**
     * 递归压栈
     */
    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;
        }

    }

}

Results are as follows:

Exception in thread "main" stack length is :20739
java.lang.StackOverflowError
    at com.example.demo.jvm.StackOverflowTest.stackLeak(StackOverflowTest.java:20)
    at com.example.demo.jvm.StackOverflowTest.stackLeak(StackOverflowTest.java:20)

In the case of VM parameters -Xss parameter is not set, the stack depth of the thread of memory support is 20739, the test result with the memory size of the machine-related, but the second point above how to test it? Normally, if it is single-threaded, it is difficult to test the memory leak situations, so multithreaded do? We 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{

    /**
     * 栈大小
     */
    private int stackLength = 1;

    /**
     * 递归压栈
     */
    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 is not under suspended animation cases, there will Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

Runtime constant pool overflow

  • Character constant pool overflows, the overflow stack is 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<String> 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:50253', transport: 'socket'

Character has been proved in Java8 constant pool is allocated in the heap.

Methods overflow

Before as Java7, method area located in a permanent Generation (the PermGen), and the permanent generation of stack isolation from each other, the permanent generation size when starting the JVM may set a fixed value, can not be changed; Java8 remains conceptual approach area, but in different ways to achieve . Cancel permanent generation method is stored in the element space (Metaspace), space is still not connected to the element stack, but the shared physical memory heap, the heap may be considered a logical
test code is as follows, as seen rapid results, addition of 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 {

    }
}

Results are as follows:

java.lang.OutOfMemoryError: Metaspace
Dumping 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 more
Caused by: java.lang.OutOfMemoryError: Metaspace
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    ... 11 more

Process finished with exit code 1

Element space memory error, overflow with proof element space-related areas.

Summarized as follows:

  • Normal JVM tuning are changed accordingly for the stack memory and heap memory, the parameter space element
  • Yuan space is not in a virtual machine, but the use of local memory. Thus, by default, the size of the voxel space by the local memory only limited, but the size may be specified by the following parameters metaSpace:
  • -XX: MetaspaceSize, the initial size of the space, this value is reached will trigger the type unloading garbage collection, while the GC will adjust the value: If you release a lot of space, it is appropriate to reduce the value; if the release very little space then when no more than MaxMetaspaceSize, an appropriate increase in the value.
  • -XX: MaxMetaspaceSize, the largest space, the default is no limit.
  • String constant pool in the pool each VM only one copy is stored in a reference value of string constants, stored on the heap

There are more articles, please pay attention to see, more hands interview Collection
image

Guess you like

Origin www.cnblogs.com/pingyun/p/11569087.html