Java 堆和栈内存错误

Java 堆和栈内存错误

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

与栈相关的错误

每当一个进程启动时,它会自动被定义为固定的栈大小。在每个方法调用期间,调用栈上会创建一个调用帧,直到方法调用结束。当在计算机内存的栈空间中没有足够的空间来创建新的栈帧时,我们就会遇到 StackOverflowError。

示例1

下面的示例说明了StackOverflowError。

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’。在main方法中,我们声明并初始化了一个名为‘n1’的整数变量,并调用带有参数‘n1’的‘methodA’。现在,‘methodA’调用了带有‘n1’自增值的‘methodB’。再一次,‘methodB’调用了‘methodA’,这个过程循环重复多次。因此,在某一点,为该程序创建的堆栈大小耗尽,导致以下错误。

以下是我们可以采取的措施来处理StackOverflowError错误:

  • 给重复调用自己的方法设定适当的终止条件、
  • 缩小局部变量或数组的大小可能也有帮助
  • 重构代码以避免无限方法调用

示例2

现在,通过这个示例,我们将尝试找到在先前示例中发生的StackOverflowError错误的解决方案。

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。

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。

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

结论

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

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程