Java 中的堆和栈内存错误


在 Java 中,运行程序的每个接口、类、对象、变量和方法都存储在计算机内存的不同区域。堆是内存区域的一部分,其中变量、方法和类的值在运行时存储。它的分配是动态发生的,并且可以根据应用程序的需求增长或缩小。另一方面,引用变量、方法和类的名称存储在栈内存区域。但是,如果由于某种原因其分配没有得到正确处理,则可能导致内存错误,我们将在本文中讨论这些错误。

与栈相关的错误

每当一个进程启动时,它都会自动定义一个固定的栈大小。在每次方法调用期间,会在调用栈上创建一个调用帧,并且会一直持续到方法调用结束。当计算机内存的栈空间中没有剩余空间用于新的栈帧时,我们就会遇到**StackOverflowError**。

示例 1

以下示例说明了 StackOverflowError

Open Compiler
import java.lang.StackOverflowError; public class Overflw { public static void methodA(int n1) { n1++; methodB(n1); } public static void methodB(int n1) { n1++; methodA(n1); } public static void main(String []args) { int n1 = 0; methodA(n1); } }

输出

Exception in thread "main" java.lang.StackOverflowError
at Overflw.methodB(Overflw.java:10)
at Overflw.methodA(Overflw.java:6)
at Overflw.methodB(Overflw.java:10)
at Overflw.methodA(Overflw.java:6)
at Overflw.methodB(Overflw.java:10)
at Overflw.methodA(Overflw.java:6)
at Overflw.methodB(Overflw.java:10)

如您所见,示例 1 代码的输出是 StackOverflowError。在这里,我们创建了两个名为“methodA”和“methodB”的参数化用户定义方法。在主方法中,我们声明并初始化了一个整数变量“n1”为 0,并调用了“methodA”以及参数“n1”。现在,“methodA”调用了“methodB”并传递了“n1”的增量值。同样,“methodB”调用了“methodA”,并且此过程重复多次。因此,在某些时候,为该程序创建的栈大小耗尽,从而导致以下错误。

我们可以采取以下措施来处理 StackOverflowError

  • 为重复自身的方法提供适当的终止条件

  • 减少局部变量或数组的大小也可能有所帮助。

  • 重构代码以避免无限方法调用。

示例 2

现在,借助此示例,我们将尝试找到在先前示例中发生的 StackOverflowError 的解决方案。

Open Compiler
public class Overflw { public static void methodA(int n1) { n1++; methodB(n1); } public static void methodB(int n1) { n1++; int n2 = 5; int mult = n1 * n2; System.out.println("Value of n1 and n2 multiplication is: " + mult); } public static void main(String []args) { int n1 = 0; methodA(n1); } }

输出

Value of n1 and n2 multiplication is: 10

在示例 1 中,代码的问题是第 6 行和第 10 行没有终止。但在上面的示例中,我们提供了一个终止程序并打印“mult”中存储值的语句。

与堆相关的错误

JVM 的两个属性“-Xmx”和“-Xms”决定了堆的大小。此大小会影响值的存储。当 JVM 由于堆内存部分空间不足而无法分配值时,我们就会遇到**OutOfMemoryError**。

示例 1

以下示例说明了 OutOfMemoryError。

Open Compiler
public class MemoryErr { public static void main(String[] args) { String stAray[] = new String[100 * 100 * 100000]; } }

输出

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at MemoryErr.main(MemoryErr.java:3)

在上面的代码中,我们分配了一个大于堆大小的空间,因此我们得到了 OutOfMemoryError

我们可以采取以下措施来处理 OutOfMemoryError。

  • 我们可以使用 -Xmx 和 -Xms JVM 选项增加堆的大小

  • 使用适合应用程序行为的垃圾收集器也可能有所帮助。

示例 2

以下示例说明了如何使用 try 和 catch 块处理 OutOfMemoryError。

Open Compiler
public class MemoryErr { public static void main(String[] args) { try { String stAray[] = new String[100 * 100 * 100000]; } catch(OutOfMemoryError exp) { System.out.println("Application reached Max size of Heap"); } } }

输出

Application reached Max size of Heap

Learn Java in-depth with real-world projects through our Java certification course. Enroll and become a certified expert to boost your career.

结论

我们从解释每个 Java 程序所需的两个内存空间开始本文。在后面的部分中,我们讨论了与堆和栈内存相关的错误。

更新于:2023-07-21

218 次查看

启动您的 职业生涯

通过完成课程获得认证

开始
广告