Java知识学习——程序计数器

JVM内存结构组成部分包括程序计数器、虚拟机栈、本地方法栈、堆、方法区。

首先我们来看程序计数器(PC Register),在了解程序计数器的作用之前,我们先分析下面的代码。

很明显图中右侧是Java源代码,Java源代码是不能直接执行运行的,需要经过编译,即编译成左侧的二进制字节码,主要是JVM指令,正是因为这些JVM指令在不同的操作系统上都是一致的,所以Java才能够平台。

有了JVM指令之后,是不能够直接交给CPU来执行的,必须经过一个解释器将每一个JVM指令解析成机器码,然后机器码才可以直接交给CPU执行。

程序计数器就是在上述步骤中记住每一个JVM指令的下一条指令的执行地址。例如上图中,当CPU执行的getstatic #20同时,程序计数器会将下条指令astore_1的地址存储下来,当getstatic #20执行完成之后,解释器就直接从程序计数器中取astore_1的地址并进行解释然后交个CPU执行,CPU执行的时候程序计数器又会重新把aload_1的地址存储下来,依次循环。

如果没有程序计数器,就不知道接下来应该执行的是哪一条命令。

实现程序计数器是通过寄存器来实现的,寄存器是CPU中读取速度最快的单元,因为读取指令地址的操作是非常频繁的,所以在Java虚拟机在设计的时候就把CPU中的寄存器当做了程序计数器,用它来存储地址。

对于程序计数器有两个特点:线程私有的。

我们都知道Java是支持多线程的,在多个线程运行的时候,CPU会有一个调度器组件给不同的线程分配时间片,比如给线程1分配一个时间片,如果在时间片里线程1对应的没有执行完成,会对其进行一个暂存,然后交给线程2执行,当线程2执行完或者时间片用完,又切换到线程1继续执行线程1剩余的代码,如果在线程的切换过程中,要记住下一条指令的地址,还是会用到程序计数器。程序计数器跟线程一样也是私有的,属于线程的,不同的线程有对应的程序计数器。

Java虚拟机规范中规定了程序计数器中不会存在内存溢出,并不像本地方法栈、堆、方法区会有内存溢出。因此JVM的各个厂商在对JVM实现的时候不用去考虑内存溢出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章