什么是程序计数器?

程序计数器是一块 较小 的内存空间,它可以看做是当前线程所执行的字节码的 行号指示器 ;在虚拟机的概念模型里(仅仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时,就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳准、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成 ;

简单的理解为,是程序计数器保证了程序的正常执行 ;

有什么特点

  • 线程私有的
  • 是java虚拟机规范里面, 唯一 一个 没有规定任何 OutOfMemoryError 情况的区域
  • 生命周期随着线程,线程启动而产生,线程结束而消亡

为什么具有这些特点

这里重点理解 :程序计数器,可以看做是当前线程执行的字节码的 行号指示器 ,这句话;要理解这句话,需要先知道字节码文件长什么样子,看下面的代码

// java 文件被翻译为字节码的时候,字节码大概类似于下面的样子
public void haha(){
// 原来的 haha 方法内部的 java 代码,被翻译为下面的类似于汇编语言的指令
0 xxxx ....
2 xxxx ....
4 xx ...
5 xxx ...
}

上面左边的 0、2、4、5 ,就是类似于字节码的行号(实际是指令的偏移地址),程序计数器中保存中的值,就是它们;字节码解释器,就是根据它们,来执行程序的 ;

理解了程序计数器,就好理解它的这些特点了;

我们都知道,java是支持多线程的,当CPU执行权从 A 线程,转移到 B 线程的时候,JVM就要暂时挂起线程 A ,去执行线程 B ;当线程 A 再次得到CPU执行权的时候,又会挂起B线程,继续执行 A 线程 ;

我们想象下,CPU是怎么知道记住之前A线程,执行到哪一处的?
答案是,CPU根本就不会记住之前执行到哪里了,它只是埋头苦干;那是什么保证了切换线程的程序可以正常执行的;答案是 : 程序计数器 ;程序计数器里面保存的是 当前线程执行的字节码的行号(看着像行号,其实是指令地址);

那么,我们需要几个程序计数器呢?如果,我们只有一个的话,切换B线程以后,程序计数器里面保存的就是B线程所执行的字节码的行号了,再切换回A线程,就蒙圈了,不知道执行到哪里了,因为,程序计数器里面保存的是B线程当前执行的字节码地址 ;因此,我们可以想象出,要为每个线程都分配一个程序计数器,因此,程序计数器的内存空间是线程私有的 ;这样即使线程 A 被挂起,但是线程 A 里面的程序计数器,记住了A线程当前执行到的字节码的指令地址了 ,等再次切回到A线程的时候,看一下程序计数器,就知道之前执行到哪里了!

那么程序计数器,什么时候分配内存呢?我们试想下,一个线程在执行的任何期间,都会失去CPU执行权,因此,我们要从一个线程被创建开始执行,就要无时无刻的记录着该线程当前执行到哪里了!因此,线程计数器,必须是线程被创建开始执行的时候,就要一同被创建;

程序计数器,保存的是当前执行的字节码的偏移地址(也就是之前说的行号,其实那不是行号,是指令的偏移地址,只是为了好理解,才说是行号的,),当执行到下一条指令的时候,改变的只是程序计数器中保存的地址,并不需要申请新的内存来保存新的指令地址;因此,永远都不可能内存溢出的;因此,jvm虚拟机规范,也就没有规定,也是唯一一个没有规定 OutOfMemoryError 异常 的区域;

当线程执行的是本地方法的时候,程序计数器中保存的值是空(undefined);原因很简单:本地方法是C++/C 写的,由系统调用,根本不会产生字节码文件,因此,程序计数器也就不会做任何记录 ;

转自:https://blog.csdn.net/youngyouth/article/details/79868299

java虚拟机-程序计数器PC Register的更多相关文章

  1. 运行时数据区--程序计数器(PC Register)

    程序计数器(PC Register) 这里的计数器(Program Counter Register)并非为广义上所指的物理寄存器,JVM中的PC寄存器(程序计数器)是对物理PC寄存器的一种抽象模拟, ...

  2. java虚拟机--->>程序计数器

    程序计数器是一块较小的内存空间,他可以看做是当前线程所执行的行号指示器.在虚拟机的概念模型(仅是概念模型,各种虚拟机可能会通过一些更高效率的方式去实现)里,字节码解释器工作室就是通过改变这个计数器的值 ...

  3. Java内存区域之程序计数器--《深入理解Java虚拟机》学习笔记及个人理解(一)

    Java虚拟机程序计数器 在书上的P39页 程序计数器干嘛的? 有了它,字节码解释器才可以知道下一条要执行的字节码指令是哪个. 无论是取下一条指令还是分支.循环.跳转.中断.线程恢复,都需要这个程序计 ...

  4. Java虚拟机(JVM)与垃圾回收机制(GC)的详解

    一.JVM结构 根据<java虚拟机规范>规定,JVM的基本结构一般如下图所示: 从左图可知,JVM主要包括四个部分: 1.类加载器(ClassLoader):在JVM启动时或者在类运行时 ...

  5. 【JVM系列1】深入分析Java虚拟机堆和栈及OutOfMemory异常产生原因

    前言 JVM系列文章如无特殊说明,一些特性均是基于Hot Spot虚拟机和JDK1.8版本讲述. 下面这张图我想对于每个学习Java的人来说再熟悉不过了,这就是整个JDK的关系图: 从上图我们可以看到 ...

  6. Java 虚拟机运行时数据区详解

    本文摘自深入理解 Java 虚拟机第三版 概述 Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟 ...

  7. 翻译Java虚拟机的结构

    英文原版:  https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 直接谷歌翻译: Java SE规范 > Java虚拟机 ...

  8. Java虚拟机知识 总结 记录

    总结了自己这两天掌握的一些JVM相关的知识.方便自己复习. jvm全称是Java Virtual Machine(java虚拟机).它之所以被称之为是“虚拟”的,就是因为它仅仅是由一个规范来定义的抽象 ...

  9. java虚拟机规范(se8)——java虚拟机结构(二)

    2.5 运行时数据区域 java虚拟机定义了多个用于程序执行期间的运行时数据区域.这些数据区域中一些随着java虚拟机的启动而创建,随着虚拟机的退出而销毁.其他的数据区域时和线程相关的.线程相关数据区 ...

随机推荐

  1. IdentityServer流程图与相关术语

    概念图   apparch 最常见的交互是:浏览器与web应用程序通信web应用程序与web APIs进行通信基于浏览器的应用程序与web APIs通信原生应用与web APIs通信基于服务的应用程序 ...

  2. MYSQL 定时自动执行EVENT

    MySQL从5.1开始支持EVENT功能,类似Oracle和MSSQL的定时任务job功能.有了这个功能之后我们就可以让MySQL自动的执行存储过程来实现数据汇总等功能了,不用像以前哪样手动操作完成了 ...

  3. FTPHelper

    转载自 :https://blog.csdn.net/jiankunking/article/details/50016043 using System; using System.Collectio ...

  4. 教你干掉win10全家桶

    原文: 教你干掉win10全家桶 这些并不好用的自带应用例如:groove音乐,相片,股票……一直占据着我们的默认应用.如果它们是一直静静的躺在那里还好,最多不用就是了.当我们想要浏览图片或者看视频的 ...

  5. Android零基础入门第60节:日历视图CalendarView和定时器Chronometer

    原文:Android零基础入门第60节:日历视图CalendarView和定时器Chronometer 上一期学习了AnalogClock.DigitalClock和TextClock时钟组件,本期继 ...

  6. HUSTOJ的Windows版评判内核(限制内存使用)

    HUSTOJ的Windows版评判内核(一) 作者:游蓝海 个人主页:http://blog.csdn.net/you_lan_hai 2013.4.9 注:最新版本项目地址:https://gith ...

  7. File handling in Delphi Object Pascal(处理record类型)

    With new users purchasing Delphi every single day, it’s not uncommon for me to meet users that are n ...

  8. 常用json解析库比较及选择 fastjson & gson

    一.常用json解析库比较及选择 1.简介 fastjson和gson是目前比较常用的json解析库,并且现在我们项目代码中,也在使用这两个解析库. fastjson 是由阿里开发的,号称是处理jso ...

  9. Python:Numpy学习

    import numpy as np # 基础属性 array = np.array([[[1,2,3], [0,0,1]], [[1,2,3], [0,0,1]]], dtype = np.int6 ...

  10. MySql 小内存优化

    MySql5.6启动内存近500M,如在小型机内存敏感的环境可能较大,下边配置会减少较多内存,至150M以下. performance_schema = OFF innodb_buffer_pool_ ...