jvm运行时数据区之程序计数器
什么是程序计数器?
程序计数器是一块 较小 的内存空间,它可以看做是当前线程所执行的字节码的 行号指示器 ;在虚拟机的概念模型里(仅仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时,就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳准、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成 ;
———–摘抄自 周志明版 《深入理解java虚拟机》 P39
简单的理解为,是程序计数器保证了程序的正常执行 ;
有什么特点
线程私有的
是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 写的,由系统调用,根本不会产生字节码文件,因此,程序计数器也就不会做任何记录 ;
————————————————
版权声明:本文为CSDN博主「淮左白衣」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/youngyouth/article/details/79868299
jvm运行时数据区之程序计数器的更多相关文章
- JVM 运行时数据区:程序计数器、Java 虚拟机栈和本地方法栈,方法区、堆以及直接内存
Java 虚拟机可以看作一台抽象的计算机,如同真实的计算机,它也有自己的指令集和运行时内存区域. Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存(运行时内存区域)划分为若干个不同的数 ...
- Jvm运行时数据区
一:运行时数据区 Java虚拟机在执行Java程序的过程中会把它管理的内存分为若干个不同的数据区域.这些区域有着各自的用途,一级创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户 ...
- Java内存管理:Java内存区域 JVM运行时数据区
转自:https://blog.csdn.net/tjiyu/article/details/53915869 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些, ...
- JVM 运行时数据区 (三)
JVM运行时数据区 运行时数据区由 程序计数器.java虚拟机栈.本地方法栈.堆.方法区 组成: 1.程序计数器 每一个Java线程都有一个程序计数器,用于保存程序执行到当前方法的哪一个指令,它是线程 ...
- JVM总结(一):概述--JVM运行时数据区
大三下,趁着寒假重温一遍JVM,准备在一个系列来总价一下学习JVM的整个过程.争取在接下来的一个星期内更新完这一个系列,然后回家过年. JVM运行时数据区 线程私有的数据区 程序计数器 虚拟机栈 本地 ...
- JVM运行时数据区与JVM堆内存模型小结
前提 JVM运行时数据区和JVM内存模型是两回事,JVM内存模型指的是JVM堆内存模型. 那JVM运行时数据区又是什么? 它包括:程序计数器.虚拟机栈.本地方法栈.方法区.堆. 来看看它们都是干嘛的 ...
- JVM运行时数据区和垃圾回收机制
最近参考各种资料,尤其是<深入理解Java虚拟机 JVM高级特性和最佳实践>,大牛之作.把最近学习的Java虚拟机组成和垃圾回收机制总结一下. 你不会的都是新知识,学无止境,每天进步一点点 ...
- Java中的字符串常量池和JVM运行时数据区的相关概念
什么是字符串常量池 JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池 工作原理 当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量 ...
- JVM运行时数据区及对象在内存中初始化的过程
JVM运行时数据区 Java虚拟机所管理的内存区域,也称为运行时数据区,分为以下几个运行时数据区,如图所示 程序计数器:当前程序所执行字节码的行号指示器 程序计数器(Program Counter R ...
随机推荐
- 继上篇博客对安卓爬虫以及TextView更新的问题解释
只能在主线程更新ui,或者用handler传输.爬虫是在另一个异步线程进行,所以爬出来的数据对控件赋值就比较麻烦.这次使用了线程数据传到runnable将数据传到handler进行赋值. 结果图: 源 ...
- 批处理教程之cls、pause命令
cls 命令 清除屏幕.执行该命令后,屏幕上的所有信息都被清除,光标重新定位至屏幕左上角. REM 和 :: REM为注释命令,一般用来给程序加上注解,该命令后的内容不被执行,但能回显. 其次 ...
- 11/5 <backtracking> 伪BFS+回溯
78. Subsets While iterating through all numbers, for each new number, we can either pick it or not p ...
- input type属性为number时,去掉右边的上下箭头
加上样式: input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; ...
- linux翻页及字符串搜索操作
向下翻动一屏幕: space, ctrl + f, ctrl + v, ctrl + F 向下翻动半屏: d, ctrl + D 向下翻动一行: 回车, e, j 向上翻动一屏幕: b, ctrl + ...
- 洛谷4965 薇尔莉特的打字机(Trie,DP)
神仙题. 考虑在一棵 Trie 上进行染色,将可能出现的串的末尾染成黑色.答案就是黑点的个数.一开始只有 \(A\) 的末尾点是黑色. 当出现一个字符(不是退格)\(c\) 时,就要将每个黑点的 \( ...
- java web开发入门五(ssh整合)基于intellig idea
SSH整合 1.引入jar包 Struts 核心jar Hibernate 核心jar Spring Core 核心功能 Web 对web模块支持 Aop aop支持 Orm 对hiber ...
- 工作中常用的Linux命令介绍与实践
前言 做后端开发的同学,一般都会接触到服务器,而我们现在的系统用的比较多的服务器系统就是linux了,平时多多少少也会接触到一些linux下的shell命令.我们来介绍下linux一些常用的命令和使用 ...
- SpringCloud与Dubbo区别对比
1:SpringCloud与Dubbo区别对比 (1):活跃度 目前SpringCloud的活跃度明显远高于Dubbo(参考github) (2):主要区别 Dubbo Spring Cloud ...
- Ubuntu16 安装 wireshark
添加源 sudo apt-add-repository ppa:wireshark-dev/stable 更新 sudo apt-get update 安装 sudo apt-get install ...