StackOverflowError和OutOfMemoryError之间的区别是什么以及如何在应用程序中避免它们?
kos*_*osa 72
简短回答:
OutOfMemoryError 与Heap有关. StackOverflowError 与堆栈有关答案很长:
当您开始时,您JVM可以定义它可以用于处理多少RAM.JVM将其划分为某些存储位置以用于其处理目的,其中两个是Stack&Heap
如果你在内存中有大对象(或)引用的对象,那么你会看到OutofMemoryError.如果您对对象有强引用,则GC无法清除为该对象分配的内存空间.当JVM尝试为新对象分配内存而没有足够的可用空间时,它会抛出,OutofMemoryError因为它无法分配所需的内存量.
如何避免:确保GC不支持不必要的对象
所有局部变量和方法调用相关数据都将在堆栈中.对于每个方法调用,将创建一个堆栈帧,并将本地以及与方法调用相关的数据放置在堆栈帧内.方法执行完成后,将删除堆栈帧.重现这一点的一种方法是,有一个无限循环的方法调用,你会看到stackoverflow错误,因为堆栈帧将填充每个调用的方法数据但不会被释放(删除).
如何避免:确保方法调用结束(不是在无限循环中)
vai*_*olo 10
StackOverflowError当您在另一个内部执行太多方法时(例如无限递归),就会发生这种情况,这受到堆栈大小的限制。
OutOfMemoryError当 JVM 耗尽空间来分配在堆上分配的新对象时,就会发生这种情况。
想象一下,您具有如下功能
public void f(int x) {
return f(x + 1);
}
Run Code Online (Sandbox Code Playgroud)
呼叫时,呼叫将f一次又一次地呼叫。每次调用时,信息都会存储在堆栈中。由于堆栈的大小受限制,因此您将获得StackOverflowError。
现在想象下面的代码:
for (int i = 1; i > 0; i++)
vector.add(new BigObject());
Run Code Online (Sandbox Code Playgroud)
BigObject普通的Java对象在哪里。如您所见,循环永远不会终止。每个分配都是在堆上完成的,因此将用BigObjects 填充,您将获得一个OutOfMemoryError。
回顾一下:
OutOfMemoryError 创建对象时抛出StackOverflowError 调用函数时抛出| 归档时间: |
|
| 查看次数: |
17719 次 |
| 最近记录: |