程序计数器精准标记当前线程下一步要执行的字节码指令地址,是线程私有、轻量级的行号指示器,用于控制流导航、断点续传、区分Java与native方法,且永不抛出OutOfMemoryError。

Java 中程序计数器(Program Counter Register,简称 PC 寄存器)通过保存**下一条要执行的字节码指令的地址(或偏移量)**来记录线程执行位置。它不记录已执行的指令,而是始终指向“即将取指并执行”的那条指令。
它只存地址,不存数据或状态
程序计数器本身不参与计算、不存储变量、不分配对象,也不受垃圾回收影响。它就是一个纯地址指示器:
- 对 Java 方法:值为方法区中该方法字节码的精确内存地址(如 0x0000001a)或指令偏移量(如 第7行)
- 对 native 方法:值为 undefined(因为控制权交给了本地库,JVM 不再管理其指令流)
- 方法刚进入时:计数器被初始化为第一条字节码指令的地址
- 方法执行 return 或异常退出时:计数器更新为调用点之后的下一条指令地址,用于正确返回
它靠自动更新和上下文快照维持连续性
每执行完一条字节码指令,解释器会自动更新程序计数器:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 顺序执行时:计数器递增,指向下一条指令(如从偏移量 5 → 8)
- 遇到分支(if_icmpne)、循环(goto)或方法调用(invokestatic)时:计数器直接跳转到目标地址,实现流程控制
- CPU 时间片切换线程时:当前线程的 PC 值被完整保存到其私有上下文;恢复调度时,该值被重新加载,解释器从中断处继续取指
它和源码行号的映射是间接完成的
程序计数器本身只认字节码地址,但 JVM 通过 行号表(LineNumberTable) 属性建立映射关系:
立即学习“Java免费学习笔记(深入)”;
- 编译时,javac 将源码行号与对应字节码偏移量一起写入 class 文件
- 抛出异常时,JVM 用当前 PC 值查行号表,定位到具体哪一行 Java 源码
- 调试器单步执行,也是靠这个映射实现“逐行”效果,实际底层仍是按字节码指令推进
它天然线程私有,无需同步
每个线程启动时,JVM 自动为其分配独立的程序计数器空间:
- 不同线程的 PC 值互不影响,哪怕执行同一段代码
- 没有共享、不涉及锁、不会发生竞争,也永远不会抛出 OutOfMemoryError
- 这是 JVM 实现“看似并行”的基础机制之一:各线程带着自己的“执行书签”,随时可暂停和续读

















