栈内存溢出


补充下我谈一下自己的看法(我们的讨论限定于比较常见的HotSpot VM):
1.线程栈内存:线程创建时,线程占用的栈内存大小可以通过-Xss设置,那么我们可以认为 栈的深度X栈桢所占用内存=线程的栈内存大小。那么对一个线程而言,是会先达到线程的栈深度限制(StackOverFlowError)还是线程的栈内存限制(OOME)呢?栈深度在栈内存足够的情况下,不能一直去增加栈桢来加深吗?

2.JVM栈内存:对于JVM而言,其可用总内存是固定的(是多少呢?),减掉方法区的内存大小和堆内存大小,就可以大概认为剩下的是JVM的栈内存大小;但实际上JVM貌似没有显示的参数可以去设置栈内存大小,这个是令我对栈内存溢出困惑的根源。既然他没有显示的大小,那我怎么应证不是堆内存溢出,不是方法区内存溢出,而是栈内存溢出呢?







1.栈内存从概念上分 “线程的栈内存” 和 “JVM的栈内存” 两种。
2.线程的栈内存:每新建一个线程时,会分配给这个线程一个栈内存初始值,最大的大小可通过 -Xss 来设置。线程占有的栈内存大小,通过不断执行方法,生成局部变量等操作,栈桢不断增加,该线程的栈内存也不断被使用。最终达到 -Xss 的值时,会抛出StackOverFlowError。其实这里就是线程的栈内存溢出,背后的概念与 OOME 是一样的,只是jvm设计者取的名字不一样而已。
3.JVM的栈内存:当一个jvm进程启动时,会不断消耗 native memory。我们可以通过参数 -Xmx 等来设置堆内存、方法区内存的最大值,当达到阀值时,jvm就会报OOME。但是栈内存大小,则是物理机器的native memory,其上限就是native memory的上限。不断建线程消耗native memory待尽时,就会报OOME。(这一点我没有实际验证过,因为我不断新建线程的后果是电脑死机)


作者:chiukong
链接:https://www.zhihu.com/question/28637033/answer/41677862
来源:知乎
著作权归作者所有,转载请联系作者获得授权。



单线程下,xss设置太小,或者定义太多的本地变量(递归)都会导致stackoverflow。多线程下,通过不断创建新的线程就会导致oom。
-----------------------
1、那么对一个线程而言,是会先达到线程的栈深度限制(StackOverFlowError)还是线程的栈内存限制(OOME)呢? 是stackoverflow,楼主随便写个递归函数试试便知。
2、摘抄周总的一句话,栈内存溢出中的stackoverflow和oom,当栈空间无法继续分配时,到底是内存太小,还是已使用的栈空间太大,其本质只是对同一件事情的两种描述而已。不知道楼主的疑惑是否在这里。


作者:xiaomai mai
链接:https://www.zhihu.com/question/28637033/answer/41569566
来源:知乎
著作权归作者所有,转载请联系作者获得授权。



outofmemory:out of=不够,不足,memory=内存
ok,意思就是内存不够,那你搞到jvm内存不够就可以了啊。
现在我来回答你的问题“怎么产生”:
要StackOverflowError:
static int level = 1;
static void callback(){
    level++;
    System.out.println("level:"+level);
    callback();
}
要outOfMemory:
static ArrayList<byte[]> list = new ArrayList<byte[]>();
static void callback(){
    while(true){
        list.add(new byte[1024*1024]);
        System.out.println(list.size());
    }
}

写个不结束的递归函数很快就会栈益出。不断的去new新对象,堆也很快益出


栈溢出有两种,一种是stackoverflow,另一种是outofmemory,前者一般是因为方法递归没终止条件,后者一般是方法中线程启动过多。





在《java虚拟机规范中文版》第二章第五节中有这么几句话:
1.如果线程请求分配的栈容量超过java虚拟机栈允许的最大容量的时候,java虚拟机将抛出一个StackOverFlowError异常。
2.如果java虚拟机栈可以动态拓展,并且扩展的动作已经尝试过,但是目前无法申请到足够的内存去完成拓展,或者在建立新线程的时候没有足够的内存去创建对应的虚拟机栈,那java虚拟机将会抛出一个OutOfMemoryError异常。


刚看到题主在问题下的评论,xss分配的应该是每个线程的栈大小,线程数量和整个进程的大小是由操作系统来限制的。
对于单个线程,栈内存容量减小,或者变量表深度增大,就会造成StackOverFlow,这点我跟题主想的一样。
至于是堆内存溢出还是方法区内存溢出还是栈内存溢出,其实可以用一些工具比如
JConsole来监视。





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值