Java memory overflow exception (on)

Original link: http://www.cnblogs.com/qianpangzi/p/10558040.html

Previous article we talked about the data area and memory overflow JVM runtime exceptions, for which this part of the memory overflow exception is not detailed enough, this article will focus on explaining the Java memory overflow knowledge exception. If you have not read the previous article little friends, please click on the Java area of memory and memory overflow exception .

Java memory overflow exception divided into two categories: namely, memory overflow and stack overflow.In the following cases, throws a memory exception: Java heap overflow, stack virtual machines and native method stack overflow, methods and runtime constant pool area overflow, as well as local direct memory overflow, introduced one by one following about these types of abnormalities .

Java heap overflow

In the Java memory area and memory overflow exception spoken, Java heap is used to store the main object instance. Size of the memory area of ​​this part of the parameters and may be performed by -Xms -Xmx parameter, and is typically -Xms -Xmx value of the same value, in order to reduce overhead when the memory expansion or contraction.

Java heap space is limited by the physical memory and dual limit virtual machine memory (usually a virtual machine's memory will be set to be smaller than the physical memory). Therefore, if the number of object instances is increasing, while the garbage collection mechanism is not timely clean-up, the space occupied by the object instance will reach a maximum Java heap space. At this point, it will because of insufficient Java heap memory, making it impossible to allocate space for the new instance to throw an OutOfMemoryError.

Run the following code by setting -Xms20m -Xmx20m can simulate this situation:

/**
 * VM Args: -Xms20m -Xmx20m
 *
 * @author bdq
 */
public class HeapOOM {
    static class OOMObject {

    }

    public static void main(String[] args) {
        List<OOMObject> objects = new ArrayList<>();
        while (true) {
            objects.add(new OOMObject());
        }
    }
}

  

operation result:

java.lang.OutOfMemoryError: Java heap space

  

This is a common OOM that is abnormal for such exceptions, often at the same time print exception information will prompt further reason for the exception, "Java heap space" as shown above. Of course, this information alone is not sufficient to determine in the end is a small set of memory, or a memory leak (memory leaks knowledge will be covered in a later article). So we have to be supplemented by other means to further determine the source of the problem, such as adding -XX: + HeapDumpOnOutOfMemoryError parameters allows virtual machines in the event of memory overflow exception Dump the current memory heap dump snapshot, and then analyzed using related tools . Such knowledge, this article temporarily make too much to explain, in a later article will be introduced one by one.

VM stack and native method stack overflow

Why should virtual machine stack and native method stack overflow discussed together, because the HotSpot virtual machine in the virtual machine does not distinguish between native method stacks and stacks. For HotSpot, although -Xoss said parameter is used to set the size of the native method stacks, but in fact is invalid, set only by the capacity of the stack -Xss parameters.

Java Virtual Machine specification for virtual machines stack and native method stacks describes two anomalies:

  1. If the stack is greater than the depth of the thread requested the maximum depth allowed by the virtual machine, StackOverflowError will throw an exception.
  2. If the virtual machine at the time of application to extend the stack can not be enough memory space, then OutOfMemoryError is thrown.

This classification is actually not very clear, because the memory is too small or have used too much stack space will cause a stack-space allocation can not continue.

StackOverflowError conditions appear very simple, following this simple code stack overflow occurs:

public class JavaVMStackSOF {
    private int stackLength = 1;

    public void stackLeak() {
        stackLength++;
        stackLeak();
    }

    public static void main(String[] args) {
        JavaVMStackSOF javaVMStackSOF = new JavaVMStackSOF();
        try {
            javaVMStackSOF.stackLeak();
        } catch (Throwable e) {
            System.out.println("Stack length:" + javaVMStackSOF.stackLength);
            throw e;
        }
    }
}

  

Results are as follows:

 

Stack length:18663
Exception in thread "main" java.lang.StackOverflowError
	at cn.bdqfork.jvm.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:12)
	at cn.bdqfork.jvm.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:12)
	at cn.bdqfork.jvm.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:12)
	at cn.bdqfork.jvm.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:12)
    ......

  

The operation of the above results, different computers Stack length size is uncertain, abnormality information output from the point of view, because stackLeak recursive call caused by excessive layers. In most cases, the stack depth is sufficient under the parameters of the virtual machine by default.

An OutOfMemoryError more difficult to occur, generally occurs in a multithreaded environment. When you create a thread, the virtual machine is assigned a private room for the corresponding thread stack size of this space can be used -Xss parameters to set. By constantly create new process can produce memory overflow exception.

The reason is that, while the process is running, the operating system to allocate memory to process is limited, both part of the Java heap and method area accounted for most of the program counter to ignore occupied by a small piece of memory, not virtual computing machine itself uses memory, the rest is occupied by the virtual machine stack and native method stacks. Therefore, the number of threads created when you reach a certain level, the virtual machine stack and native method stacks will make the space occupied by the memory space of the process is not enough, so throw out of memory exception.

This part of the test code is as follows:

public class JavaVMStackOOM {
    private void dontStop() {
        while (true) {
            
        }
    }

    public void stackLeakByThread() {
        while (true) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    dontStop();
                }
            });
            thread.start();
        }
    }

    public static void main(String[] args) {
        JavaVMStackOOM javaVMStackOOM = new JavaVMStackOOM();
        javaVMStackOOM.stackLeakByThread();
    }
}

  

Run this code has some risk, because Java thread is not entirely user-level threads, there are mapped to parts of the operating system, so the system may produce the phenomenon of suspended animation, run carefully.

Results are as follows:

Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

  

It can be seen during our multi-threaded development, there must be a degree of certainty for the number of threads, thread pool multiplexing is necessary.

Limited by space reasons, the remaining knowledge will be the next one to explain.

 

Reproduced in: https: //www.cnblogs.com/qianpangzi/p/10558040.html

Guess you like

Origin blog.csdn.net/weixin_30294709/article/details/94783926