为了账号安全,请及时绑定邮箱和手机立即绑定

图解JVM系列:揭秘运行时数据区的设计与实现

标签:
大数据

大家好,我是大圣,很高兴又和大家见面。

今天给大家带来图解 JVM 系列的第三篇文章,主要讲 JVM 的运行时数据区落地。本次大纲如下:

file

前面知识回顾

回顾

我把 JVM 的工作流程画了一张图,如下:

file

下面我把前面两篇文章讲的东西和这张流程图对应一下

第一篇文章

在第一篇文章里面我们说了三个问题:

  1. JVM 的核心作用:就是把.class 文件拿来跑跑翻译成机器指令

对应图片中红色框框起来的部分:

file

  1. 代码到 JVM 上的过程:Java 代码会被编译成 .class 文件

对应图片中绿色框框起来的部分:

file

  1. Java 的跨平台优势:Java 字节码(.class 文件)和 JVM 提供了跨平台

第二篇文章

在第二篇文章里面我们说了两个问题,对应图片中绿色框框起来的部分:

file

  1. JVM 加载 class 字节码文件过程

  2. 类加载器和双亲委派模型(重点)

小结

通过前面两篇文章的讲解,已经把我们编写的.java 文件编译成 .class 字节码文件的过程讲清楚了,

然后 JVM 加载 .class 字节码文件的过程也讲清楚了。

接下来的文章我们就要深入 JVM 的内部,来讲一下它的内部工作机制等。

JVM 运行时数据区落地

JVM 运行时数据区的设计理念

说起 JVM 运行时数据区很多人都能背出来,比如堆、方法区、虚拟机栈等。如下图:

file

那你知道 JVM 运行时数据区为什么会这样设计吗?

设计理念

其实 JVM 虚拟机是参考物理机实现的,那我们的物理计算机的实现是遵循一个什么样的模型呢?计算机一般是按照下面这个模型实现的

file

这图大家学计算机的肯定都不陌生,这是冯·诺依曼结构。下面我就从冯·诺依曼结构推演出我们JVM 运行时数据区的各个部分。

输入输出

其实我们理解 JVM(Java 虚拟机)如何工作时,可以把它比作一台计算机。在物理计算机中,我们有输入设备(如键盘、鼠标)和输出设备(如显示器、打印机)。

对于 JVM 来说,它的“输入”是 Java 的 class 文件,这些文件包含了 Java 程序的字节码。JVM 的任务是将这些字节码“翻译”或转换成机器码,即可以被操作系统直接执行的指令

物理计算机的存储器:

在物理计算机中,存储器是用来存储程序和数据的。它通常包括主存储器(如 RAM)和辅助存储器(如硬盘)。

主存储器存储当前正在执行的程序和需要快速访问的数据。辅助存储器则用于存储大量数据和不常用的程序。

JVM 中的堆和方法区:
堆(Heap)

在 JVM 中,堆是用于存储运行时数据的主要区域,特别是对象实例和数组。

这与物理计算机的主存储器有相似之处,因为它们都用于存储正在使用的数据。JVM 的堆是所有线程共享的,这里面的对象可以被程序中的任何线程访问

方法区(Method Area)

方法区用于存储已被虚拟机加载的类信息、常量、静态变量等数据。

这与物理计算机中的程序存储区相似,因为它们都存储程序代码和相关数据。

在一些 JVM 实现中,方法区被称作“永久代”(PermGen)或“元空间”(Metaspace),但它的基本功能是相似的。

总结来说,JVM 的堆和方法区在功能上类似于物理计算机的存储器。
JVM 的堆主要用于存储实例数据,就像物理计算机的主存储器用于存储当前正在使用的数据。

而方法区则存储程序代码和静态数据,类似于物理计算机中用于存储程序和长期数据的存储区域。

这两个区域在 JVM 中是至关重要的,因为它们共同支持了 Java 程序的执行和数据存储。

物理计算机的控制器和运算器

在物理计算机中,控制器负责取指令和分析指令,而运算器处理逻辑和算术运算。

这些指令和运算是直接在 CPU 上进行的,CPU 通过各种寄存器和缓存来执行这些操作。

JVM 中的相应实现:

在 JVM 中,执行 Java 字节码的任务是由 JVM 的执行引擎承担的,这相当于物理计算机中的 CPU。

Java 虚拟机栈:

它对应于物理计算机中的控制流程。每当一个新的方法被调用,一个新的栈帧就会被压入 Java 虚拟机栈中。这个栈帧包含了方法的局部变量、操作数栈和方法返回时的状态,这类似于 CPU 在执行一个程序时用到的寄存器。

本地方法栈:

当 Java 程序调用本地(例如 C 语言)方法时,这些方法的执行不是在 Java 虚拟机栈上,而是在本地方法栈上。这反映了物理计算机中处理不同类型指令(比如操作系统调用和应用程序指令)的方式。

程序计数器:

它类似于物理计算机中的指令寄存器,记录着当前线程执行的指令地址。这确保了即使在多线程环境中,每个线程在执行时都能知道接下来要执行哪条指令。

总结来说,JVM 通过这些运行时数据区(Java 虚拟机栈、本地方法栈和程序计数器)来模拟物理计算机中的控制器和运算器的功能。

每个 Java 线程在 JVM 中都有自己的这些数据区,这允许 JVM 同时执行多个线程,每个线程都有自己的执行上下文,就像物理计算机可以并行处理多个进程或线程一样。

总结

本文回顾

这篇文章主要就讲了运行时数据区的设计理念,就是这个东西它到底是怎么出现的,它是参考我们的物理计算机来设计的。

提起物理计算机设计我们都知道冯·诺依曼结构,然后我根据冯·诺依曼结构推出了我们JVM 运行时数据区的各个部分。

这样以后再说JVM 运行时数据区的时候,大家就不用死记硬背了,可以按照这种设计理念去理解记忆,一直都不会忘记的。

建议

建议大家记住这种 JVM 工作流程图,没事就可以拿出来看一看,然后自己可以对着这张图回想我们文章的内容。

如果有的内容我说的不够深入,大家也可以去深入学习一下。

面试的时候,面试官问到运行时数据区,大家也可以把这种设计理念说给面试官听,面试官会眼前一亮的,觉得你有研究。

预告

我们讲了运行时数据区的设计理念与落地,下一篇文件会说运行时数据区每一部分的作用,然后通过一个真实的代码案例,来讲解运行时数据区每一部分存储的是什么内容等。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消