Bohr-L Bohr-L
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

刘博

I'm a slow walker, But I never walk backwards.
首页
技术
常见面试题
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据处理与存储类

  • Spring 生态类

  • 缓存问题类

  • 多线程类

  • JVM 类

    • JVM 中一次完整的 GC 流程(从 ygc 到 fgc)是怎样的
    • 如何判断对象可以被回收
    • 你知道哪些垃圾收集算法
    • 虚拟机为什么使用元空间替换了永久代
    • 简述 CMS 垃圾收集器的工作流程,它有什么优缺点?
    • 简述一下 JVM 的内存模型
    • 说说堆和栈的区别
    • 简述 Java 的对象结构
    • JVM 中的即时编译器(JIT)如何工作?
    • 什么是内存屏障?JVM 如何使用内存屏障保证指令执行顺序?
    • 如何排查和解决 JVM 内存泄漏问题?有哪些常用的工具和方法?
    • JVM 如何处理异常?try-catch-finally 结构在字节码层面是如何实现的?
    • MySQL 类

    • Java 8 + 特性类

    • 其他技术类

    • 常见面试题
    • JVM 类
    刘博
    2025-12-28
    目录

    JVM 如何处理异常?try-catch-finally 结构在字节码层面是如何实现的?

    # 1. JVM 处理异常的核心机制

    JVM 通过 “异常表(Exception Table)” 和 “异常处理器(Exception Handler)” 处理异常,核心流程如下:

    • 当 Java 代码抛出异常(throw new Exception())或执行时出现错误(如空指针、数组越界),JVM 会创建Throwable对象(异常实例);
    • JVM 遍历当前方法的 “异常表”,查找能处理该异常的 “异常处理器”(匹配异常类型和代码范围);
    • 若找到匹配的处理器,JVM 跳转到处理器对应的字节码地址执行(如catch块);
    • 若未找到,JVM 将异常向上抛给调用者方法,重复上述流程;若所有方法均未处理,JVM 终止程序,输出异常堆栈信息。

    # 2. try-catch-finally 在字节码层面的实现

    以以下代码为例,分析字节码层面的实现逻辑:

    java

    运行

    public class ExceptionDemo {
        public static void main(String[] args) {
            try {
                int a = 1 / 0; // 可能抛出ArithmeticException
            } catch (ArithmeticException e) {
                System.out.println("捕获算术异常");
            } finally {
                System.out.println("执行finally块");
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # (1)异常表(Exception Table)的生成

    编译后,字节码中会生成 “异常表”,记录try块的代码范围、异常类型、catch块的入口地址,示例如下(通过javap -v ExceptionDemo.class查看):

    plaintext

    Exception table:
       from    to  target type
           0    10    13   Class java/lang/ArithmeticException
    
    1
    2
    3
    • from/to:try块的字节码起始地址(0)和结束地址(10);
    • target:catch块的字节码起始地址(13);
    • type:能处理的异常类型(ArithmeticException)。
    # (2)try 块的执行
    • 字节码中,try块的代码(int a = 1 / 0)正常执行;
    • 若执行过程中抛出ArithmeticException,JVM 查询异常表,发现该异常在from-to范围内且类型匹配,跳转到target地址(13)执行catch块。
    # (3)catch 块的执行
    • catch块的字节码逻辑:创建ArithmeticException对象(e),执行System.out.println("捕获算术异常");
    • 执行完成后,JVM 会跳转到finally块的入口地址,确保finally块执行。
    # (4)finally 块的强制执行

    finally块的核心特性是 “无论try块是否抛出异常,finally块都会执行”,字节码层面通过以下两种方式实现:

    • 方式 1:正常执行路径:若try块未抛出异常,执行完try块后,JVM 会插入跳转指令,强制跳转到finally块;
    • 方式 2:异常执行路径:若try块抛出异常并被catch块处理,执行完catch块后,JVM 同样插入跳转指令,跳转到finally块;
    • 特殊情况:try/catch 块中执行 return:若try块或catch块中有return语句,JVM 会先将return的返回值存入临时变量,再执行finally块,最后从临时变量中取出返回值执行return(确保finally块执行后再返回)。
    # (5)未捕获异常的处理

    若try块抛出的异常未被任何catch块处理(如抛出NullPointerException,但catch块只处理ArithmeticException),JVM 会:

    1. 执行finally块(若存在);
    2. 将异常向上抛给调用者方法(main方法的调用者是 JVM);
    3. JVM 调用Thread.dispatchUncaughtException(),输出异常堆栈信息,终止程序。

    上次更新: 12/30/2025
    如何排查和解决 JVM 内存泄漏问题?有哪些常用的工具和方法?
    MySQL 为什么一定要有一个主键

    ← 如何排查和解决 JVM 内存泄漏问题?有哪些常用的工具和方法? MySQL 为什么一定要有一个主键→

    最近更新
    01
    CPU 使用率较高排查和解决
    12-29
    02
    JVM OOM 问题如何排查和解决
    12-29
    03
    接口防刷怎么实现?
    12-29
    更多文章>
    Theme by Vdoing | Copyright © 2025-2026 Bohr-L's note
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式