深入浅出 JVM 之运行时数据区-程序计数器

深入浅出 JVM 之运行时数据区-程序计数器

文章目录

  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。

系统环境:

  • JDK 1.8

参考地址:

深入浅出 JVM 系列文章

一、程序计数器概述

程序计数器 (Program Counter Register) 又叫做程序计数寄存器,是 Java 虚拟机运行时数据区中,属于 某个线程 的一块私有内存区域。

在 Java 虚拟机中的字节码解释器工作时,就是通过改变程序计数器的值,来选取下一条需要执行的字节码指令,其可以看做是 当前线程 所指向的字节码的行号指示器,如分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖程序计数器来完成。

二、字节码的执行原理

编译后的字节码在没有经过 JIT(实时编译器) 编译前,是通过字节码解释器进行解释执行。其执行原理为:

字节码解释器读取内存中的字节码,按照顺序操作程序计数器选取下一条需要执行的字节码指令,然后读取字节码指令,读取一个指令就将其翻译成固定的操作,根据这些操作进行分支,循环,跳转等动作。

三、程序计数器的作用

从字节码的执行原理来看,单线程的情况下程序计数器是可有可无的,因为即使没有程序计数器的情况下,程序会按照指令顺序执行下去,即使遇到了分支跳转这样的流程,也会按照跳转到指定的指令处继续顺序执行下去,是完全能够保证执行顺序的。

不过在 Java 应用程序中,很多代码流程都需要使用多线程来提高并发性能,而 Java 中的多线程是通过 CPU 时间片轮转来实现的,某个线程在执行的过程中可能会因为时间片耗尽而挂起,当它再次获取时间片时,需要从挂起的地方继续执行。

每个线程都有程序计数器,而程序计数器的作用正是用于记录当前线程执行到的字节码指令位置,这样可以保证当前线程时间片耗尽后,等到再次获得 CPU 时间片开始执行时,能够恢复到上次时间片最后执行到的正确位置。

CPU时间片: CPU 分配给各个程序的时间,每一个线程被分配一个时间段,称作时间片。用户可以打开多个程序同时运行,在视觉错觉上以为是并发运行的,但是实际上由于只有一个 CPU,一次只能处理程序要求的一部分,如何实现公平处理,那就是引用时间片,让每一个程序轮流执行。

四、程序计数器的特点

  • ① 程序计数器占用的内存空间非常小,可以忽略不计;
  • ② 程序计数器属于线程独有,其生命周期与线程的生命周期保持一致;
  • ③ 程序执行的时候,程序计数器是有值的,其记录的是程序正在执行的字节码的地址;
  • ④ 程序计数器是《Java 虚拟机规范》中,唯一一个没有规定任何 OutofMemeryError 的区域;
  • ⑤ 执行 Native 本地方法时,程序计数器的值为空,因为 Native 方法是 JVM 通过 JNI 调用本地 C/C++ 库来实现,而非 Java 字节码实现,所以无法统计;

---END---


  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。