什么会导致java.lang.StackOverflowError
?我得到的堆栈打印输出根本不是很深(只有5个方法)。
发布于 2013-07-08 18:01:23
检查方法的任何递归调用。这主要是由方法的递归调用引起的。一个简单的例子是
public static void main(String... args) {
Main main = new Main();
main.testMethod(1);
}
public void testMethod(int i) {
testMethod(i);
System.out.println(i);
}
在这里,当调用testMethod时,System.out.println(i);将被反复推送到堆栈。
发布于 2010-07-08 02:29:57
JVM的一个(可选)参数是堆栈大小。我是-Xss。我不知道默认值是什么,但是如果堆栈上的东西总数超过了这个值,你就会得到那个错误。
一般来说,无限递归是导致这种情况的原因,但如果你看到了这种情况,你的堆栈跟踪应该有5个以上的帧。
尝试添加一个-Xss参数(或增加一个参数的值),看看这种情况是否会消失。
发布于 2013-06-20 11:35:54
实际导致java.lang.StackOverflowError的原因通常是无意的递归。对我来说,这通常是当我打算调用覆盖方法的超级方法时。例如在本例中:
public class Vehicle {
public void accelerate(float acceleration, float maxVelocity) {
// set the acceleration
}
}
public class SpaceShip extends Vehicle {
@Override
public void accelerate(float acceleration, float maxVelocity) {
// update the flux capacitor and call super.accelerate
// oops meant to call super.accelerate(acceleration, maxVelocity);
// but accidentally wrote this instead. A StackOverflow is in our future.
this.accelerate(acceleration, maxVelocity);
}
}
首先,当我们调用一个函数时,知道幕后发生了什么是很有用的。参数和调用方法的地址被推送到堆栈上(请参见http://en.wikipedia.org/wiki/Stack_(abstract_data_type)#Runtime_memory_management,以便被调用的方法可以访问参数,并且当被调用的方法完成时,可以在调用后继续执行。但是因为我们是递归地调用this.accelerate(acceleration,maxVelocity) (当一个方法调用自己时,递归是松散的。有关更多信息,请参见http://en.wikipedia.org/wiki/Recursion_(computer_science),我们处于一种称为无限递归的情况下,我们不断地在调用堆栈上堆积参数和返回地址。由于调用堆栈的大小有限,我们最终会耗尽空间。调用堆栈上的空间耗尽称为溢出。这是因为我们试图使用比我们拥有的更多的堆栈空间,而数据从字面上溢出堆栈。在Java语言中,这会导致运行时异常java.lang.StackOverflow,并会立即停止程序。
上面的例子稍微简化了一些(尽管它发生在我身上的次数比我愿意承认的要多)。同样的事情可能会以一种更间接的方式发生,使其更难追踪。但是,通常情况下,一旦发生StackOverflow,它通常很容易解决。
从理论上讲,没有递归的堆栈溢出也是可能的,但在实践中,这似乎是相当罕见的事件。
https://stackoverflow.com/questions/3197708
复制相似问题