JVM:Java运行时数据区域----程序计数器

简介: JVM:Java运行时数据区域----程序计数器

最近在学习JVM,拜读了周志明的《深入理解Java虚拟机:JVM高级特性与最佳实践》,书中内容读后受益匪浅,让我对Java虚拟机有了完整的认识,这真是学习JVM的一本好书。结合自己的理解,整理一下笔记。


运行时数据区域


Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。


如图:Java虚拟机运行时数据区


20190420234532794.png


简单的理解为JVM为了方便数据的处理,把它的大内存分为了几个用途不同的小内存来方便Java程序的运行。


Java 虚拟机的内存模型分为两部分:一部分是线程共享的,包括 Java 堆和方法区;另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内存。


好了,到我们今天要讲的重点了


程序计数器


什么是程序计数器?

周志明在《深入理解Java虚拟机》中如是说:

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

简单理解:

当程序启动时,尤其是多线程情况下,为了保证程序正常运行,为每一个线程配备一个程序计数器,通过程序计数器来为每个线程记录进度。


程序计数器的特点


线程私有

具有生命周期,随线程启动产生,线程结束消亡

唯一 一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

如果线程正在执行的是Java 方法,计数器记录的是正在执行的虚拟机字节码指令地址

如果正在执行的是Native 方法,则计数器记录值为空(Undefined)

我们知道Java虚拟机的多线程是通过线程轮流(涉及时间片轮转算法)切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。而每个线程都配备一个独立的程序计数器来确保线程切换后能恢复到正确的执行位置是很棒的一个做法。


通过代码来直观了解一下程序计数器


代码如下:

package practice7;
public class Test {
   public int calc(){
          int a = 3;
          int b = 7;
          int c = 2;
          return ( a + b ) * c;
   }
}

我们将上面代码的java文件先编译成Class文件再使用 javap 反汇编工具看下class 文件中数据格式,如下图


20190422110722622.png


图中已经指出字节码指令的偏移地址,偏移地址对应的iconst、bipush 等等是jvm 中的操作指令,这是入栈指令


当int类型 取值-1~5采用iconst指令      取值-128~127采用bipush指令。


当执行到方法calc()时在当前的线程中会创建相应的程序计数器,在计数器中为存放执行地址 (红框中的)0 2 3…等等

 说明在我们程序运行过程中计数器中改变的只是值,而不会随着程序的运行需要更大的空间,也就不会发生溢出情况。


参考:JVM 程序计数器


内容较为粗糙宽泛,细细了解后会加深解析!

目录
相关文章
|
18天前
|
数据采集 JSON Java
Java爬虫获取微店快递费用item_fee API接口数据实现
本文介绍如何使用Java开发爬虫程序,通过微店API接口获取商品快递费用(item_fee)数据。主要内容包括:微店API接口的使用方法、Java爬虫技术背景、需求分析和技术选型。具体实现步骤为:发送HTTP请求获取数据、解析JSON格式的响应并提取快递费用信息,最后将结果存储到本地文件中。文中还提供了完整的代码示例,并提醒开发者注意授权令牌、接口频率限制及数据合法性等问题。
|
19天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
83 14
|
2月前
|
存储 NoSQL Java
使用Java和Spring Data构建数据访问层
本文介绍了如何使用 Java 和 Spring Data 构建数据访问层的完整过程。通过创建实体类、存储库接口、服务类和控制器类,实现了对数据库的基本操作。这种方法不仅简化了数据访问层的开发,还提高了代码的可维护性和可读性。通过合理使用 Spring Data 提供的功能,可以大幅提升开发效率。
68 21
|
23天前
|
前端开发 JavaScript Java
Java打包jar运行时分离lib和jar
在`pom.xml`的`build`节点中,设置`packaging`为`jar`,并配置插件分离依赖库到`lib`目录和资源文件到`resources`目录。这样可以在运行时通过`-Dloader.path=lib,resources`加载外部依赖和资源文件,便于独立升级依赖库和修改资源文件,而无需重新打包程序。具体插件包括`maven-dependency-plugin`、`maven-resources-plugin`和`spring-boot-maven-plugin`等。
58 1
|
13天前
|
Java API 数据处理
深潜数据海洋:Java文件读写全面解析与实战指南
通过本文的详细解析与实战示例,您可以系统地掌握Java中各种文件读写操作,从基本的读写到高效的NIO操作,再到文件复制、移动和删除。希望这些内容能够帮助您在实际项目中处理文件数据,提高开发效率和代码质量。
19 0
|
2月前
|
存储 分布式计算 Hadoop
基于Java的Hadoop文件处理系统:高效分布式数据解析与存储
本文介绍了如何借鉴Hadoop的设计思想,使用Java实现其核心功能MapReduce,解决海量数据处理问题。通过类比图书馆管理系统,详细解释了Hadoop的两大组件:HDFS(分布式文件系统)和MapReduce(分布式计算模型)。具体实现了单词统计任务,并扩展支持CSV和JSON格式的数据解析。为了提升性能,引入了Combiner减少中间数据传输,以及自定义Partitioner解决数据倾斜问题。最后总结了Hadoop在大数据处理中的重要性,鼓励Java开发者学习Hadoop以拓展技术边界。
63 7
|
2月前
|
SQL Java 数据库连接
【潜意识Java】深入理解MyBatis的Mapper层,以及让数据访问更高效的详细分析
深入理解MyBatis的Mapper层,以及让数据访问更高效的详细分析
102 1
|
2月前
|
存储 监控 算法
Java JVM 面试题
Java JVM(虚拟机)相关基础面试题
|
2月前
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
612 166
|
4月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
727 1

热门文章

最新文章