一篇文章带你快速理解JVM运行时数据区 、程序计数器详解 (手画详图)值得收藏!!!

简介: 一篇文章带你快速理解JVM运行时数据区 、程序计数器详解 (手画详图)值得收藏!!!

微信截图_20220523204113.png

受多种情况的影响,又开始看JVM 方面的知识。


1、Java 实在过于内卷,没法不往深了学。


2、面试题问的多,被迫学习。


3、纯粹的好奇。 很喜欢一句话:“八小时内谋生活,八小时外谋发展。” --- 望别日与君相见时,君已有所成。共勉



地点:湖南一个小城市邵阳


作者:博主


一、运行时数据区


图示:


微信截图_20220523204239.png



补充一个点: 在运行时数据区中,灰色的为单独线程私有的,红色的为多个线程共享的,即:


  • 每个线程:独立包括程序计数器、栈、本地栈。


  • 线程间共享:堆、堆外内存(永久代或元空间、代码缓存)


运行时数据区的完整图:


不同的JVM对于内存的划分方式和管理机制存在着部分差异。这里给出一张完整的运行时数据区图。🤱


微信截图_20220523204307.png


看完上面的两张图,我想应该对JVM中所谓的运行时数据区有个大概印象了吧。下面👇会给大家再给大家带来一些粗略的讲解哈。


运行时数据区概述:


当我们通过前面的:类的加载-> 验证 -> 准备 -> 解析 -> 初始化 这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到我们运行时数据区 🤸‍♂️


微信截图_20220523204346.png


运行时数据区,Runtime Data Area,用于保存java程序运行过程中需要用到的数据和相关信息;经常说的把数据读到内存,包括类加载之后的信息,从磁盘读取文件信息等。即:==Java虚拟机在执行Java程序的过程中,会将涉及的数据划分到不同的内存区域去管理。==


课间休息会


微信截图_20220523204411.png


二、程序计数器(Program Counter)


概述:


程序计数器是用于存放下一条指令所在单元的地址的地方。


当执行一条指令时,首先需要根据PC中存放的指令地址,将指令由内存取到指令寄存器中,此过程称为“取指令”。与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址。此后经过分析指令,执行指令。完成第一条指令的执行,而后根据PC取出第二条指令的地址,如此循环,执行每一条指令。


JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟。


程序计数器是线程私有内存,是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError的区域。


代码讲解


JAVA代码编译后的字节码在未经过JIT(实时编译器)编译前,其执行方式是通过“字节码解释器”进行解释执行。简单的工作原理为解释器读取装载入内存的字节码,按照顺序读取字节码指令。读取一个指令后,将该指令“翻译”成固定的操作,并根据这些操作进行分支、循环、跳转等流程。


例如:


微信截图_20220523204454.png


使用javap -c -verbose ClassCode.class 命令反编译出来结果为:


微信截图_20220523204533.png


从上面的描述中,可能会产生程序计数器是否是多余的疑问。


因为沿着指令的顺序执行下去,即使是分支跳转这样的流程,跳转到指定的指令处按顺序继续执行是完全能够保证程序的执行顺序的。假设程序永远只有一个线程,这个疑问没有任何问题,也就是说并不需要程序计数器。但实际上程序是通过多个线程协同合作执行的。


首先我们要搞清楚JVM的多线程实现方式。JVM的多线程是通过==CPU时间片轮转==(即线程轮流切换并分配处理器执行时间)算法来实现的。也就是说,某个线程在执行过程中可能会因为时间片耗尽而被挂起,而另一个线程获取到时间片开始执行。当被挂起的线程重新获取到时间片的时候,它要想从被挂起的地方继续执行,就必须知道它上次执行到哪个位置,在JVM中,通过程序计数器来记录某个线程的字节码执行位置。因此,程序计数器是具备线程隔离的特性,也就是说,每个线程工作时都有属于自己的独立计数器。即私有性,每个线程都拥有私有的程序计数器


使用PC寄存器存储字节码指令地址有什么用呢?


其实在上一段文字中已经写了,这里写个缩句哈。


因为CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行。


JVM的字节码解释器就需要通过改变PC寄存器的值来明确下一条应该执行什么样的字节码指令。


微信截图_20220523204628.png


那么 PC寄存器为什么被设定为私有的?(图解)


由于CPU时间片轮限制,众多线程在并发执行过程中,任何一个确定的时刻,一个处理器或者多核处理器中的一个内核,只会执行某个线程中的一条指令。


这样必然导致经常中断或恢复,如何保证分毫无差呢?每个线程在创建后,都会产生自己的程序计数器和栈帧,程序计数器在各个线程之间互不影响。


还是决定手画几张图来帮助大家来理解记忆:


微信截图_20220523204653.png


我想看完这个图,大家对pc 程序计数器 为什么是私有是有个大概的理解了吧。


自言自语:


更多的文章在后面拉,还会有的,路还长勒。

人生路上选择众多,但不要害怕选择,那都是人生宝贵的财富,


目录
相关文章
|
2月前
|
存储 Java
【JVM】 程序计数器(Program Counter Register)
【JVM】 程序计数器(Program Counter Register)
45 1
|
4天前
|
小程序 Java 程序员
【Java探索之旅】我与Java的初相识(二):程序结构与运行关系和JDK,JRE,JVM的关系
【Java探索之旅】我与Java的初相识(二):程序结构与运行关系和JDK,JRE,JVM的关系
15 0
|
11天前
|
存储 安全 Java
JVM之本地方法栈和程序计数器和堆
JVM之本地方法栈和程序计数器和堆
13 0
|
2月前
|
缓存 监控 Java
深入剖析JVM的OOM | 内存溢出如何影响JVM运行及应对策略
深入剖析JVM的OOM | 内存溢出如何影响JVM运行及应对策略
105894 1
|
2月前
|
存储 Java 编译器
【JVM】运行时数据区域
【JVM】运行时数据区域
20 0
|
4月前
|
存储 安全 Java
JVM之程序计数器和栈
Java虚拟机(JVM)是运行Java程序的关键组件,它负责将Java源代码转换为可执行的字节码,并在运行时管理内存、执行程序等。
|
4月前
|
存储 Java C++
JVM 运行时数据区
JVM 运行时数据区
|
11天前
|
Java
JVM之本地内存以及元空间,直接内存的详细解析
JVM之本地内存以及元空间,直接内存的详细解析
25 0
|
4天前
|
存储 Java
深入理解Java虚拟机:JVM内存模型
【4月更文挑战第30天】本文将详细解析Java虚拟机(JVM)的内存模型,包括堆、栈、方法区等部分,并探讨它们在Java程序运行过程中的作用。通过对JVM内存模型的深入理解,可以帮助我们更好地编写高效的Java代码,避免内存溢出等问题。
|
2月前
|
缓存 算法 安全
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(二)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
18 0