`
如若_晴
  • 浏览: 108275 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

java产生StackOverflowError的原因是什么?

阅读更多
1、你是不是开来很多线程,然后这些线程还递归了?原因应该是栈被你用完了吧。
2、死循环本身是不会StackOverflow的,只有无限递归的时候会出现。原则上循环嵌套次数本身是没有限制的,限制的是占用的栈空间,如果你的函数里定义了很多很多变量,栈空间就会用完得比较快。
Java里面有没有这种语法不清楚,C#中间可以把struct定义成整个展开的形式,这样一个struct可能就占很大的空间,而且是unboxing的,放到栈上可能一层就会导致StackOverflow……

3、 支持 "循环嵌套次数本身是没有限制的",这个应该是错的.我看过官方文档,里面说是因为嵌套的层次太深导致的.但是嵌套层次要去到什么深度才引起java.lang.StackOverflowError,我现在还没找到.
我的函数嵌套了1k层左右,当初我也以为是栈空间占用太多了导致的,所以把不必要的变量都去掉,单纯的去递归,但是还是报StackOverflowError.最后把算法改成不用递归,用循环,问题就解决了.
4、递归就算什么变量都不要也是消耗栈空间的,每次调用都要在栈里面压一大堆乱七八糟的东西,比如说返回地址,比如说参数,还可能有执行上下文等等。
5、JVM里会有两种StackOverflowError, 一种是对应JVM stack, 一种是对应Native Method stack. 我们一般说的都是JVM stack.
每一个JVM线程维护自己的JVM stack. JVM stack里面存放 JVM栈帧. 栈帧中存放 数据和中间结果(本地变量数组, 操作符栈, 和对runtime 常量池的引用). 这些数据都比较小(对象都在堆中, 栈帧仅存放对象引用), 所以想单纯通过 在栈帧中存放大数据的方法 去引入StackOverflowError, 基本是不现实的.一般都是因为方法调用嵌套层数过大.
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.2
JVM stack的大小是可以调节的, sun的windows jvm6 x64,jvm栈默认大小为1024k.可以通过-Xss1024k来调节.
http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom
做一点实验:
  private int aa=0; private void aaa(){     System.out.println(aa++);     aaa(); }  @Test public void test3243(){     aaa(); }测试结果:  -server -Xss128k 输出946时溢出java栈  -server -Xss512k 输出5418时溢出java栈  -server -Xss1280k 输出14363时溢出java栈  -server -Xss12800k 输出252223时溢出java栈

6、函数栈溢出 就会出现这个错误 一些语言是可以设置递归的最大深度的(比如Python) 如果体验过这个 你就明白这里的溢出是咋回事了
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics