是什么导致java.lang.StackOverflower错误
什么会导致是什么导致java.lang.StackOverflower错误,java,callstack,stack-overflow,Java,Callstack,Stack Overflow,什么会导致java.lang.StackOverflowerError?我得到的堆栈打印输出根本不是很深(只有5个方法)。JVM的一个(可选)参数是堆栈大小。它是-Xss。我不知道默认值是什么,但如果堆栈上的内容总量超过该值,您将得到该错误 通常,无限递归是造成这种情况的原因,但如果您看到了这一点,堆栈跟踪将有5帧以上 尝试添加一个-Xss参数(或增加一个参数的值),看看这是否会消失。导致java.lang.StackOverflower错误的实际原因通常是无意的递归。对我来说,通常是在我打算为
java.lang.StackOverflowerError
?我得到的堆栈打印输出根本不是很深(只有5个方法)。JVM的一个(可选)参数是堆栈大小。它是-Xss。我不知道默认值是什么,但如果堆栈上的内容总量超过该值,您将得到该错误
通常,无限递归是造成这种情况的原因,但如果您看到了这一点,堆栈跟踪将有5帧以上
尝试添加一个-Xss参数(或增加一个参数的值),看看这是否会消失。导致java.lang.StackOverflower错误的实际原因通常是无意的递归。对我来说,通常是在我打算为overidden方法调用super方法的时候。例如在这种情况下:
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);
}
}
首先,当我们调用函数时,了解幕后发生了什么是很有用的。参数和调用方法的地址被推送到堆栈上(请参阅),以便被调用的方法可以访问参数,并且当被调用的方法完成时,可以在调用后继续执行。但是,由于我们递归地调用这个.acceleration(加速度,maxVelocity)(当方法调用自身时,递归是松散的。有关更多信息,请参阅)我们处于一种称为无限递归的情况,我们不断在调用堆栈上堆积参数和返回地址。由于调用堆栈的大小是有限的,我们最终会耗尽空间。调用堆栈上的空间不足称为溢出。这是因为我们试图使用比现有更多的堆栈空间,数据实际上溢出了堆栈。在Java编程语言中,这将导致运行时异常Java.lang.StackOverflow,并将立即停止程序
上面的例子有点简化(尽管它发生在我身上的次数比我想承认的要多)。同样的事情也可能以更全面的方式发生,这使得追踪起来有点困难。然而,一般来说,一旦发生堆栈溢出,通常很容易解决
从理论上讲,在没有递归的情况下也有可能出现堆栈溢出,但在实践中,这似乎是一个相当罕见的事件。检查是否存在对方法的任何递归调用。它主要是在对方法进行递归调用时产生的。一个简单的例子是
public static void main(String... args) {
Main main = new Main();
main.testMethod(1);
}
public void testMethod(int i) {
testMethod(i);
System.out.println(i);
}
这里是System.out.println(i);调用testMethod时将被重复推送到堆栈。我用hibernate创建了一个程序,在其中我创建了两个POJO类,它们都有一个彼此的对象作为数据成员。在main方法中,当我试图将它们保存到数据库中时,我也遇到了这个错误 这是因为两个类都在互相引用,因此创建了一个导致此错误的循环
因此,请检查您的程序中是否存在任何此类关系 当Java应用程序调用函数调用时,会在调用堆栈上分配堆栈帧。堆栈框架包含被调用方法的参数、其本地参数和方法的返回地址 返回地址表示执行点,在调用的方法返回后,程序将从该执行点继续执行。如果没有新堆栈帧的空间,则由Java虚拟机(JVM)抛出 最常见的可能耗尽Java应用程序堆栈的情况是递归 请看一看
就我而言,我有两项活动。在第二个活动中,我忘记在onCreate方法上添加super
super.onCreate(savedInstanceState);
当线程堆栈继续增大直到达到最大限制时,可能会发生堆栈溢出异常 正在调整堆栈大小(Xss和Xmso)选项 我建议您查看以下链接: StackOverflower错误有许多可能的原因,正如您在链接中所看到的……什么是
java.lang.StackOverflowerr
抛出错误java.lang.StackOverflowerError
,表明应用程序的堆栈已耗尽,原因是深度递归,即您的程序/脚本递归太深
细节
StackOverflowerError
扩展了VirtualMachineeError
类,该类表示JVM已经或已经耗尽了资源,无法进一步操作。VirtualMachineError
扩展了错误
类,用于指示应用程序不应捕获的严重问题。方法不能在其throw
子句中声明此类错误,因为这些错误是不可能发生的异常情况
一个例子
最小、完整且可验证的示例
:
package demo;
public class StackOverflowErrorExample {
public static void main(String[] args)
{
StackOverflowErrorExample.recursivePrint(1);
}
public static void recursivePrint(int num) {
System.out.println("Number: " + num);
if(num == 0)
return;
else
recursivePrint(++num);
}
}
控制台输出
解释
当Java应用程序调用函数调用时,会在调用堆栈上分配一个堆栈帧。堆栈帧包含被调用方法的参数、其本地参数和方法的返回地址。返回地址表示执行点,在调用的方法返回后,程序将从该执行点继续执行。如果没有新堆栈帧的空间,Java虚拟机(JVM)将抛出堆栈溢出错误 最常见的可能耗尽Java应用程序堆栈的情况是递归。在递归中,方法在执行过程中调用自身
递归
是最强大的通用编程技术之一,但必须谨慎使用,以避免出现堆栈溢出错误
工具书类
- Hibernate用户解析数据时的解决方案:
@JsonManagedReference
@OneToMany(mappedBy = "owner", fetch = FetchType.EAGER)
Set<Car> cars;
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "owner_id")
private Owner owner;
我有这个错误,因为我正在分析obje的列表
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "owner_id")
private Owner owner;
@ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY,cascade = CascadeType.ALL)
Set<BusinessUnitMaster> businessUnits =new HashSet<>();
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(
name = "BusinessUnitRoles",
joinColumns = {@JoinColumn(name = "unit_id", referencedColumnName = "record_id")},
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "record_id")}
)
private Set<Role> roles=new HashSet<>();
roleRepository.save(role);
businessUnitMasterRepository.save(businessUnitMaster);