stack栈异常

2020-05-23  本文已影响0人  程序男保姆

1 StackOverflowError

  线程请求的栈深度大于虚拟机所允许的深度。


/***
 * 栈 测试类
 */
public class JavaVMStackSOF  {

    private static Integer count = 1;
    public static void main(String[] args) {
        a();
    }

    /***
     * 通过递归方法调用
     */
    public static void a() {
        try {
            count ++;
            a();
        }catch (Throwable e){
            System.out.println(count);
            System.out.println(e);
        }
    }
}

设置不同的jvm参数,得到不同的结果
-Xss   -X stack size 设置栈内存大小
-Dfile.encoding=UTF-8  -Xss128k
1000
java.lang.StackOverflowError

-Dfile.encoding=UTF-8  -Xss256k
2000
java.lang.StackOverflowError

-Dfile.encoding=UTF-8  -Xss1024k
7504
java.lang.StackOverflowError

1 内存大小: 增加每个线程的虚拟机栈大小,这种方式虽然简便,但在多线程的情况下,随着每个线程所属的虚拟机栈的大小的增加,所能执行的线程也就随之减少了
2 从Java程序上无疑就是检查是否出现方法的不合理递归调用,从而减少栈帧的创建和及时的回收。
我们使用这种方式来解决StackOverflowError异常时,通常要权衡这两个反比因素。

2 OutOfMemoryError

  如果虚拟机栈可以动态扩展当扩展时无法申请到足够的内存时,就会OutOfMemoryError异常。


public class JavaVMStackOOM {

    public static void main(String[] args) {
        b();
    }

    /***
     *  不断的创建线程
     */
    public static void b() {
        while (true){
            new Thread(() -> {
                // 使用死循环 避免线程被回收
                while (true){}
            }).start();
        }
    }

}


设置不同的jvm参数,得到不同的结果
-Xss   -X stack size 设置栈内存大小
-Dfile.encoding=UTF-8  -Xss 2M
 
java的线程时映射到操作系统的内核线程上的,因此上述代码执行时有较大风险,可能会导致操作系统假死(果然死机了)。

如果虚拟机在拓展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。
在虚拟机栈和本地方法栈发生OOM异常场景如下:当Java 程序启动一个新线程时,若没有足够的空间为该线程分配Java栈(一个线程Java栈的大小由-Xss设置决定),JVM将抛出OutOfMemoryError异常

上一篇下一篇

猜你喜欢

热点阅读