资讯专栏INFORMATION COLUMN

JVM 栈(stack)溢出案例

ConardLi / 2087人阅读

摘要:如果设置的太小可能会很容易出现异常。以后每个线程堆栈大小为,以前每个线程堆栈大小为。示例代码通过无限递归来模拟栈溢出捕获的是,而不是。不让进程结束,便于使用分析工具来查看内存情况执行结果

介绍

当启动一个新线程时,JVM就会给这个线程分配一个Java栈(这个栈的内存大小由-Xss参数来设置)。

一个Java栈的基本单位是帧,每一次函数调用就会生成栈帧,占用一定的栈空间。当函数本身需要的内存过大,或者函数调用函数(依赖调用或者递归调用)太深,超过了-Xss设置的内存大小,就会抛出StackOverflowError异常。

-Xss:默认值 1M,控制每个线程占用的内存,这个参数决定了函数调用的最大深度。如果设置的太小可能会很容易出现 StackOverflowError 异常。    

JDK 5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

示例代码
public class StackOverflow {

    private static int deep = 1;

    /**
     * 通过无限递归来模拟栈溢出
     */
    private static void recursion() {
        deep++;
        recursion();
    }

    public static void main(String[] args) {
        try {
            recursion();
        } catch (Throwable e) { // catch 捕获的是 Throwable,而不是 Exception。因为 StackOverflowError 不属于 Exception 的子类。
            System.out.println("Stack deep : " + deep);
            e.printStackTrace();
        }

        // 不让进程结束,便于使用分析工具来查看内存情况
        try {
            Thread.sleep(24 * 60 * 60 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

执行结果

Stack deep : 11429
java.lang.StackOverflowError
    at com.song.StackOverflow.call(StackOverflow.java:16)
    at com.song.StackOverflow.call(StackOverflow.java:17)
    ...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75126.html

相关文章

  • 关于JVM内存溢出的原因分析及解决方案探讨

    摘要:内存溢出分配的内存空间超过系统内存。内存泄漏的原因分析由大块组成堆,栈,本地方法栈,程序计数器,方法区。内存溢出的原因分析内存溢出是由于没被引用的对象垃圾过多造成没有及时回收,造成的内存溢出。小结栈内存溢出程序所要求的栈深度过大导致。 showImg(https://segmentfault.com/img/bVbweuq?w=563&h=300); 前言:JVM中除了程序计数器,其他...

    xuexiangjys 评论0 收藏0
  • 十种JVM内存溢出的情况,你碰到过几种?

    摘要:内存溢出的情况就是从类加载器加载的时候开始出现的,内存溢出分为两大类和。以下举出个内存溢出的情况,并通过实例代码的方式讲解了是如何出现内存溢出的。内存溢出问题描述元空间的溢出,系统会抛出。这样就会造成栈的内存溢出。 导言: 对于java程序员来说,在虚拟机自动内存管理机制的帮助下,不需要自己实现释放内存,不容易出现内存泄漏和内存溢出的问题,由虚拟机管理内存这一切看起来非常美好,但是一旦...

    ShevaKuilin 评论0 收藏0
  • JVM详解1.Java内存模型

    摘要:编译参见深入理解虚拟机节走进之一自己编译源码内存模型运行时数据区域根据虚拟机规范的规定,的内存包括以下几个运运行时数据区域程序计数器程序计数器是一块较小的内存空间,他可以看作是当前线程所执行的字节码的行号指示器。 点击进入我的博客 1.1 基础知识 1.1.1 一些基本概念 JDK(Java Development Kit):Java语言、Java虚拟机、Java API类库JRE(...

    TANKING 评论0 收藏0
  • 摘记《深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)》

    摘要:第章内存区域与内存溢出异常运行时数据区域虚拟机在执行程序的过程中会把它所管理的内存划分为若干个不同的数据区域。即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。 第2章 Java内存区域与内存溢出异常 2.2 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。根据《Java虚拟机规范(Java SE 7版)...

    zoomdong 评论0 收藏0
  • jvm调优

    摘要:垃圾回收垃圾检测引用计数法和可达性分析算法。引用计数法给一个对象添加引用计数器,每当有个地方引用它,计数器就加,引用失效就减。通常会在老年代内存被占满时将会触发,回收整个堆内存。 基础知识 JVM - HotSpot内存布局(1.8之前版本) showImg(https://segmentfault.com/img/bVMdE6?w=1024&h=608); 1.8版本开始,持久区没有...

    jemygraw 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<