java StackOverflowError 和 OutOfMemoryError 有什么区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11435613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 05:07:34  来源:igfitidea点击:

What's the difference between StackOverflowError and OutOfMemoryError

java

提问by Ifozest

What's the difference between StackOverflowError and OutOfMemoryError and how to avoid them in application?

StackOverflowError 和 OutOfMemoryError 之间有什么区别以及如何在应用程序中避免它们?

回答by kosa

Short answer:

简答:

  • OutOfMemoryErroris related to Heap.
  • StackOverflowErroris related to stack
  • OutOfMemoryError与堆有关。
  • StackOverflowError与堆栈有关

Long answer:

长答案:

When you start JVMyou define how much RAM it can use for processing. JVMdivides this into certain memory locations for its processing purpose, two of those are Stack& Heap

当您开始时,您JVM可以定义它可以用于处理的 RAM 量。JVM出于处理目的将其划分为某些内存位置,其中两个是Stack&Heap

If you have large objects (or) referenced objects in memory, then you will see OutofMemoryError. If you have strong references to objects, then GC can't clean the memory space allocated for that object. When JVM tries to allocate memory for new object and not enough space available it throws OutofMemoryErrorbecause it can't allocate the required amount of memory.

如果您在内存中有大对象(或)引用对象,那么您将看到OutofMemoryError. 如果您对对象有强引用,则 GC 无法清理为该对象分配的内存空间。当 JVM 尝试为新对象分配内存但没有足够的可用空间时,它会抛出,OutofMemoryError因为它无法分配所需的内存量。

How to avoid: Make sure un-necessary objects are available for GC

如何避免:确保不需要的对象可用于 GC

All your local variables and methods calls related data will be on the stack. For every method call, one stack frame will be created and local as well as method call related data will be placed inside the stack frame. Once method execution is completed, the stack frame will be removed. ONE WAY to reproduce this is, have an infinite loop for method call, you will see stackoverflowerror, because stack frame will be populated with method data for every call but it won't be freed (removed).

所有与本地变量和方法调用相关的数据都将在堆栈中。对于每个方法调用,将创建一个堆栈框架,并将本地以及与方法调用相关的数据放置在堆栈框架内。一旦方法执行完成,堆栈帧将被移除。重现这种情况的一种方法是,对方法调用进行无限循环,您将看到stackoverflow错误,因为堆栈帧将填充每次调用的方法数据,但不会被释放(删除)。

How to avoid: Make sure method calls are ending (not in an infinite loop)

如何避免:确保方法调用结束(不是无限循环)

回答by Mihai Maruseac

Imagine you have a function like the following

想象一下你有一个像下面这样的函数

public void f(int x) {
    return f(x + 1);
}

When you'll call it the call will call fagain and again and again. At each call a bit of information is stored on the stack. Since the stack is limited in size you will get a StackOverflowError.

当你打电话给它时,电话会f一次又一次地打电话。每次调用时,都会在堆栈中存储一些信息。由于堆栈的大小有限,您将获得一个StackOverflowError.

Now imagine the following code:

现在想象下面的代码:

for (int i = 1; i > 0; i++)
    vector.add(new BigObject());

where BigObjectis a normal Java object. As you see, the loop never terminates. Each allocation is done on the heap thus it will be filled with BigObjects and you will get an OutOfMemoryError.

哪里BigObject是一个普通的 Java 对象。如您所见,循环永远不会终止。每次分配都是在堆上完成的,因此它将用BigObjects填充,您将获得一个OutOfMemoryError.

To recap:

回顾一下:

  • OutOfMemoryErroris thrown when you are creating objects
  • StackOverflowErroris thrown when you are calling functions
  • OutOfMemoryError创建对象时抛出
  • StackOverflowError调用函数时抛出

回答by vainolo

StackOverflowErrorhappens when you execute too many methods one inside another (for example with an infinite recursion), which is limited by the size of the stack.

StackOverflowError当您在另一个内部执行太多方法(例如无限递归)时,会发生这种情况,这受到堆栈大小的限制。

OutOfMemoryErrorhappens when the JVM runs out of space to allocate new objects, which are allocated on the heap.

OutOfMemoryError当 JVM 用完空间来分配在堆上分配的新对象时会发生这种情况。

回答by Not a bug

In Java Virtual Machine there are several memory area defined :

在 Java 虚拟机中定义了几个内存区域:

  1. Java Virtual Machine stacks
  2. Heap area
  3. Method area
  4. Run time constant pool
  5. Native method stacks
  1. Java 虚拟机堆栈
  2. 堆区
  3. 方法区
  4. 运行时常量池
  5. 本机方法栈

In all above, you can choose your precision that memory allocated to those memory area will be fixed or will be changed dynamically at runtime.

在上述所有内容中,您可以选择分配给这些内存区域的内存将是固定的还是在运行时动态更改的精度。

Now about the question, OutOfMemoryErroris applicable for all of the above listed. OutOfMemoryErrorwill be thrown if memory expansion of any of the memory area will be attempted but enough memory is not available to allocate.

现在关于这个问题,OutOfMemoryError适用于上面列出的所有内容。OutOfMemoryError如果将尝试对任何内存区域进行内存扩展,但没有足够的内存可供分配,则将抛出该异常。

and StackOverFlowErroris applicable for Native Method Stackand Java Virtual Machine Stack. StackOverFlowErrorwill be thrown If the computation in a thread requires a larger stack than is permitted.

并且StackOverFlowError适用于Native Method StackJava Virtual Machine StackStackOverFlowError如果线程中的计算需要比允许的更大的堆栈,则将抛出。

For Detailed reference you can read THE STRUCTURE OF THE JAVA VIRTUAL MACHINE

有关详细参考,您可以阅读JAVA 虚拟机的结构

回答by Lazy Coder

There are two(2) areas in memory the heap and stack.

内存中有两(2)个区域,即堆和堆栈。

  1. stack memoryis used to store local variables and function call.
  2. heap memoryis used to store objects in Java
  1. 堆栈内存用于存储局部变量和函数调用。
  2. 堆内存用于在Java中存储对象

If there is no memory left in stack for storing function call or local variable, JVM will throw java.lang.StackOverFlowError,

如果堆栈中没有剩余内存用于存储函数调用或局部变量,JVM 将抛出java.lang.StackOverFlowError

while if there is no more heap space for creating object, JVM will throw java.lang.OutOfMemoryError:

而如果没有更多的堆空间用于创建对象,JVM 将抛出java.lang.OutOfMemoryError

回答by Arshak Manukyan

The following exceptional conditions are associated with Java Virtual Machine stacks:

If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError.

If Java Virtual Machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java Virtual Machine stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.

The following exceptional condition is associated with the heap:

If a computation requires more heap than can be made available by the automatic storage management system, the Java Virtual Machine throws an OutOfMemoryError.

The following exceptional condition is associated with the method area:

If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an OutOfMemoryError.

The following exceptional condition is associated with the construction of the run-time constant pool for a class or interface:

When creating a class or interface, if the construction of the run-time constant pool requires more memory than can be made available in the method area of the Java Virtual Machine, the Java Virtual Machine throws an OutOfMemoryError.

The following exceptional conditions are associated with native method stacks:

If the computation in a thread requires a larger native method stack than is permitted, the Java Virtual Machine throws a StackOverflowError.

If native method stacks can be dynamically expanded and native method stack expansion is attempted but insufficient memory can be made available, or if insufficient memory can be made available to create the initial native method stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.

以下异常情况与 Java 虚拟机堆栈相关联:

如果线程中的计算需要比允许的更大的 Java 虚拟机堆栈,则 Java 虚拟机将抛出 StackOverflowError

如果 Java 虚拟机堆栈可以动态扩展,并且尝试扩展但没有足够的内存来实现扩展,或者如果没有足够的内存可以为新线程创建初始 Java 虚拟机堆栈,则 Java 虚拟机机器抛出OutOfMemoryError

以下异常情况与堆相关联:

如果计算需要的堆多于自动存储管理系统所能提供的堆,Java 虚拟机将抛出OutOfMemoryError

以下异常条件与方法区相关联:

如果方法区中的内存无法满足分配请求,Java 虚拟机将抛出 OutOfMemoryError

以下异常条件与类或接口的运行时常量池的构建相关:

在创建类或接口时,如果运行时常量池的构造需要的内存多于 Java 虚拟机的方法区中可用的内存,则 Java 虚拟机将抛出OutOfMemoryError

以下异常情况与本机方法堆栈相关联:

如果线程中的计算需要比允许的更大的本机方法堆栈,则 Java 虚拟机将抛出 StackOverflowError。

如果可以动态扩展本机方法堆栈并尝试扩展本机方法堆栈但可以提供足够的内存,或者如果可以提供足够的内存来为新线程创建初始本机方法堆栈,则 Java 虚拟机将抛出OutOfMemoryError.

https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-2.html

https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-2.html

2.5.2. Java Virtual Machine Stacks

2.5.2. Java 虚拟机堆栈

2.5.3. Heap

2.5.3. 堆

2.5.4. Method Area

2.5.4. 方法区

2.5.5. Run-Time Constant Pool

2.5.5. 运行时常量池

2.5.6. Native Method Stacks

2.5.6. 本地方法栈

2.6. Frames

2.6. 框架

回答by Jaweria Siddiqui

StackOverflowError

堆栈溢出错误

  • It is related to Stack memory.
  • It occurs when Stack is full.
  • It is thrown when you call a method and there is no space left in the stack.
  • It occurs when you are calling a method recursively without proper terminating condition.
  • How to avoid? Make sure that methods are finishing their execution and leaving the stack memory.
  • 它与堆栈内存有关。
  • 它发生在堆栈已满时。
  • 当您调用一个方法并且堆栈中没有剩余空间时,它会被抛出。
  • 当您在没有适当终止条件的情况下递归调用方法时,就会发生这种情况。
  • 如何避免?确保方法正在完成它们的执行并离开堆栈内存。

OutOfMemoryError

内存不足错误

  • It is related to heap memory.
  • It occurs when heap is full.
  • It is thrown when you create a new object and there is no space left in the heap.
  • It occurs when you are creating lots of objects in the heap memory.
  • How to avoid? Try to remove references to objects which you don't need anymore.
  • 它与堆内存有关。
  • 它发生在堆满时。
  • 当您创建一个新对象并且堆中没有剩余空间时,它会被抛出。
  • 当您在堆内存中创建大量对象时会发生这种情况。
  • 如何避免?尝试删除对不再需要的对象的引用。

回答by Saurabh

java.lang.StackOverFlowError:
1) Thrown when stack memory is full
2) The data related to method like parameters, local variables or references to objects are stored in this block. When the method finishes its execution, this block is removed from the stack along with data stored in it.
Whenever you call a method, it must finish its execution and leave the stack memory. If your methods are staying in the stack then stack will be full and JVM will throw java.lang.StackOverflowError. E.g:

java.lang.StackOverFlowError:
1)堆栈内存已满时抛出
2) 与方法相关的数据,如参数、局部变量或对象引用等存储在此块中。当该方法完成其执行时,该块与存储在其中的数据一起从堆栈中移除。
每当你调用一个方法时,它必须完成它的执行并离开堆栈内存。如果您的方法保留在堆栈中,那么堆栈将已满,JVM 将抛出 java.lang.StackOverflowError。例如:

public class FactorialExample
{
    private static void factorial(int i)
    {
        factorial((i+1) * i);   //calling itself with no terminating condition
    }

    public static void main(String[] args) 
    {
        factorial(1);
    }
}

java.lang.OutOfMemoryError:
1) Thrown when heap memory is full.
2) JVM is unable to allocate the memory to new objects.
The objects you create in java are stored in the heap memory. When the objects are no more required, they must be removed from the memory. Garbage collector removes the unwanted objects from the heap memory. If your objects have live references, garbage collector doesn't remove them. It removes only those objects which don't have live references.

java.lang.OutOfMemoryError:
1)当堆内存已满时抛出。
2) JVM 无法为新对象分配内存。
你在java中创建的对象存储在堆内存中。当不再需要这些对象时,必须将它们从内存中删除。垃圾收集器从堆内存中删除不需要的对象。如果您的对象具有实时引用,垃圾收集器不会删除它们。它只删除那些没有实时引用的对象。

回答by EI CHO

Through the JVM specification, there are 5 data areas.

通过JVM规范,有5个数据区。

For JVM Stacks data areas, the spec said the memory size of JVM Stacks can be fixed or dynamically adjustable like the heap area.

对于 JVM Stacks 数据区,规范说 JVM Stacks 的内存大小可以像堆区一样固定或动态调整。

When runs out of JVM Stacks memory, there are two cases:
1. If JVM Stacks is implemented as a fixed size, JVM will throw a StackOverflowError.
2. Otherwise, just like the heap area, JVM will throw OutOfMemoryErrorwhen failed to allocate more memory.

当 JVM Stacks 内存用完时,有两种情况:
1. 如果 JVM Stacks 实现为固定大小,JVM 将抛出StackOverflowError
2. 否则,就像堆​​区一样,JVM在分配更多内存失败时会抛出OutOfMemoryError

Any not only for the JVM Stacks area, memory allocations for other data areas will also case OutOfMemoryError due to insufficient memory resources.

任何不仅仅针对JVM Stacks区域,其他数据区域的内存分配也会因为内存资源不足而出现OutOfMemoryError。

For more information, see the JVM specification - Run-Time Data Areas

有关更多信息,请参阅JVM 规范 - 运行时数据区

回答by Navneet

StackOverflowError : Thrown when a stack overflow occurs because an application recurses too deeply.

StackOverflowError :当由于应用程序递归太深而发生堆栈溢出时抛出。

OutOfMemoryError : Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

OutOfMemoryError :当 Java 虚拟机由于内存不足而无法分配对象时抛出,垃圾收集器无法提供更多内存。