📜  Java中的运行时堆栈机制 [使用更新的图像]

📅  最后修改于: 2022-05-13 01:55:13.280000             🧑  作者: Mango

Java中的运行时堆栈机制 [使用更新的图像]

先决条件: Java中的异常

对于每个线程,JVM(Java虚拟机)都会创建一个运行时堆栈。

  • 线程中执行的每个调用都存储在堆栈中。
  • 运行时堆栈中的每个条目称为激活记录或堆栈帧。
  • 在线程完成每个方法调用后,从堆栈的相应条目中删除。
  • 完成所有方法后,堆栈将为空,并且该运行时堆栈将在终止线程之前被 JVM 销毁。

让我们看一下下面的程序,以了解运行时堆栈的工作原理。

案例1:正常(优雅终止)

运行时栈的构建:

  1. 首先,主线程会调用main()方法,对应的入口会在栈中。
  2. 之后 main() 方法被称为 fun() 方法,它将存储在堆栈中。
  3. 在 fun() 方法中,调用了 moreFun() 方法。因此,最后 moreFun() 将存储在堆栈中。
  4. 最后,moreFun() 没有调用任何方法,它会打印Hello Geeks!
Java
// Java program to illustrate run time
// Run-time stack mechanism in
// normal flow of Exception handling
 
class Geeks {
    public static void main(String[] args)
    {
        fun();
    }
   
    public static void fun()
    {
        moreFun();
    }
   
    public static void moreFun()
    {
        System.out.println("Hello Geeks!");
    }
}


Java
// Java program to illustrate run time
// Run-time stack mechanism in
// normal flow of Exception handling
 
public class ExceptionHandling {
    public static void main(String[] args)
    {
        fun();
    }
    public static void fun()
    {
        moreFun();
        System.out.println("Method fun");
    }
    public static void moreFun()
    {
        System.out.println(10 / 0);
        System.out.println("Method moreFun");
    }
}


输出
Hello Geeks!

运行时堆栈的破坏:打印后Hello Geeks! ,其对应的条目将从堆栈中删除,它将转到 fun() 方法,并且没有任何执行内容,这就是为什么从堆栈中删除 fun() 方法的条目等等。当堆栈为空时,JVM 会销毁运行时堆栈。

案例2:异常(异常终止)

运行时栈的构建:

  1. 下面的示例在方法 moreFun() 位置有 ArithmeticException,JVM 将检查是否存在任何异常处理代码。如果不是,则方法 moreFun() 将负责创建异常对象,因为在方法 moreFun() 上引发了异常,并且将从堆栈中删除相应的条目,并且控制转到方法 fun()。
  2. JVM 再次去调用者方法检查它是否有任何异常处理代码都没有。如果不是,JVM 会异常终止该方法并从堆栈中删除相应的条目。
  3. 上述过程一直持续到主线程。如果主线程(main 方法)没有任何异常处理代码,JVM 也会异常终止 main 方法,默认异常处理程序负责将异常消息打印到作为 JVM 一部分的输出屏幕。

Java

// Java program to illustrate run time
// Run-time stack mechanism in
// normal flow of Exception handling
 
public class ExceptionHandling {
    public static void main(String[] args)
    {
        fun();
    }
    public static void fun()
    {
        moreFun();
        System.out.println("Method fun");
    }
    public static void moreFun()
    {
        System.out.println(10 / 0);
        System.out.println("Method moreFun");
    }
}

运行时错误:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at ExceptionHandling.moreFun(ExceptionHandling.java:16)
    at ExceptionHandling.fun(ExceptionHandling.java:11)
    at ExceptionHandling.main(ExceptionHandling.java:7)