程序计数器(PC Register)
一、基础定义
程序计数器是JVM运行时数据区中线程私有 的内存区域,每个线程独立持有一份。
内部存储当前线程正在执行的字节码指令行号/内存地址,作为字节码解释器的执行指针。
二、核心作用
- 字节码执行导航
Java源码编译为class字节码,一行Java代码会拆分为多条字节码指令;程序计数器记录当前执行到第几条指令,解释器根据该地址读取下一条要执行的指令。
示例:System.out.println("hello world")拆分为4条字节码,计数器依次记录0、3、5、8指令偏移。 - 线程切换断点恢复
CPU时间片轮转切换线程时,会保存当前线程的程序计数器值;线程重新获得CPU资源后,通过计数器恢复到上次中断的字节码位置继续执行。 - 记录异常行号
抛出异常时,JVM通过程序计数器映射源码行号,打印精准的异常堆栈行数。
三、配套工具:javap
命令 javap -v 类名.class
功能:打印方法字节码、操作栈深度、局部变量表、行号映射表,直观查看字节码指令与PC计数器偏移地址。
四、关键特性
- 线程私有
多线程并发时,每个线程拥有独立PC寄存器,互不干扰;线程切换仅保存/恢复自身计数器,不会互相覆盖执行位置。 - 唯一无OOM的内存区域
JVM规范规定:程序计数器是唯一一块不会发生OutOfMemoryError的运行时内存区,内存占用极小,仅存储数字偏移量。 - 区分Java方法与本地方法
- 执行Java方法:PC记录字节码指令地址;
- 执行native本地方法:PC值为
undefined,无有效存储内容。
五、面试简答
问:什么是程序计数器?有什么作用?
答:
程序计数器属于JVM运行时数据区,是线程私有内存,每个线程独立一份,专门存储当前线程正在执行的字节码指令偏移地址。
作用:1. 给字节码解释器提供执行地址,逐行执行字节码;2. CPU线程切换时保存断点,线程恢复后继续执行;3. 异常时定位源码出错行。
它是JVM中唯一不会产生OOM的内存区域,执行native本地方法时计数器无有效值。