java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > OutOfMemoryError StackOverflowError

OutOfMemoryError内存不足和StackOverflowError堆栈溢出示例详解

作者:小名源治

这篇文章主要为大家介绍了OutOfMemoryError内存不足和StackOverflowError堆栈溢出示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

OutOfMemoryError(内存不足)

如果虚拟机的栈内存允许动态扩展,当扩展栈容量无法申请到足够的内存时,将抛出
OutOfMemoryError异常。

StackOverflowError(堆栈溢出)

如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。

测试一:单线程中通过两个方法不断相互调用

单线程中,通过两个方法不断的相互调用,栈的深度到达了虚拟机的最大深度。

结果:抛出StackOverflowError异常,

public class JVMStackOverflow {
    static void  dfs(){
        a();
    }
    private static void a() {
        dfs();
    }
    public static void main(String[] args) throws Throwable {
        dfs();
    }
}

测试二:使用单线程,定义了大量的本地变量

使用单线程,定义了大量的本地变量,增大此方法帧中本地变量表的长度。

结果:抛出StackOverflowError异常,异常出现时输出的堆栈深度相应缩小。

public class JavaVMStackSOF {
    private static int stackLength = 0;
    public static void test() {
        long unused1, unused2, unused3, unused4, unused5,
                unused6, unused7, unused8, unused9, unused10,
                unused11, unused12, unused13, unused14, unused15,
                unused16, unused17, unused18, unused19, unused20,
                unused21, unused22, unused23, unused24, unused25,
                unused26, unused27, unused28, unused29, unused30,
                unused31, unused32, unused33, unused34, unused35,
                unused36, unused37, unused38, unused39, unused40,
                unused41, unused42, unused43, unused44, unused45,
                unused46, unused47, unused48, unused49, unused50,
                unused51, unused52, unused53, unused54, unused55,
                unused56, unused57, unused58, unused59, unused60,
                unused61, unused62, unused63, unused64, unused65,
                unused66, unused67, unused68, unused69, unused70,
                unused71, unused72, unused73, unused74, unused75,
                unused76, unused77, unused78, unused79, unused80,
                unused81, unused82, unused83, unused84, unused85,
                unused86, unused87, unused88, unused89, unused90,
                unused91, unused92, unused93, unused94, unused95,
                unused96, unused97, unused98, unused99, unused100;
        stackLength ++;
        test();
        unused1 = unused2 = unused3 = unused4 = unused5 =
                unused6 = unused7 = unused8 = unused9 = unused10 =
                        unused11 = unused12 = unused13 = unused14 = unused15 =
                                unused16 = unused17 = unused18 = unused19 = unused20 =
                                        unused21 = unused22 = unused23 = unused24 = unused25 =
                                                unused26 = unused27 = unused28 = unused29 = unused30 =
                                                        unused31 = unused32 = unused33 = unused34 = unused35 =
                                                                unused36 = unused37 = unused38 = unused39 = unused40 =
                                                                        unused41 = unused42 = unused43 = unused44 = unused45 =
                                                                                unused46 = unused47 = unused48 = unused49 = unused50 =
                                                                                        unused51 = unused52 = unused53 = unused54 = unused55 =
                                                                                                unused56 = unused57 = unused58 = unused59 = unused60 =
                                                                                                        unused61 = unused62 = unused63 = unused64 = unused65 =
                                                                                                                unused66 = unused67 = unused68 = unused69 = unused70 =
                                                                                                                        unused71 = unused72 = unused73 = unused74 = unused75 =
                                                                                                                                unused76 = unused77 = unused78 = unused79 = unused80 =
                                                                                                                                        unused81 = unused82 = unused83 = unused84 = unused85 =
                                                                                                                                                unused86 = unused87 = unused88 = unused89 = unused90 =
                                                                                                                                                        unused91 = unused92 = unused93 = unused94 = unused95 =
                                                                                                                                                                unused96 = unused97 = unused98 = unused99 = unused100 = 0;
    }
    public static void main(String[] args) {
        try {
            test();
        }catch (Error e){
            System.out.println("stack length:" + stackLength);
            throw e;
        }
    }
}

可见无论是由于栈帧太大还是虚拟机栈容量太小,当新的栈帧内存无法分配的时候,HotSpot虚拟机抛出的都是StackOverflowError异常。可是如果在允许动态扩展栈容量大小的虚拟机上,相同代码则会导致不一样的情况。譬如远古时代的Classic虚拟机,这款虚拟机可以支持动态扩展栈内存的容量,它运行方法二就会产生OutOfMemoryError异常。

测试三:什么情况下可以产生OutOfMemoryError异常呢?

通过不断建立线程的方式,在HotSpot上也是可以产生内存溢出异常的。但是这样产生的内存溢出异常和栈空间是否足够并不存在任何直接的关系,主要取决于操作系统本身的内存使用状态。甚至可以说,在这种情况下,给每个线程的栈分配的内存越大,反而越容易产生内存溢出异常。

public class JVMStackOOM {
    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) throws Throwable {
        JVMStackOOM oom = new JVMStackOOM();
        oom.stackLeakByThread();
    }
}

以上就是OutOfMemoryError内存不足和StackOverflowError堆栈溢出示例详解的详细内容,更多关于OutOfMemoryError StackOverflowError的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文