大家好,我是大圣,很高兴又和大家见面。
今天给大家带来图解 JVM 系列的第三篇文章,主要讲 JVM 的运行时数据区落地。本次大纲如下:
前面知识回顾
回顾
我把 JVM 的工作流程画了一张图,如下:
下面我把前面两篇文章讲的东西和这张流程图对应一下
第一篇文章
在第一篇文章里面我们说了三个问题:
- JVM 的核心作用:就是把.class 文件拿来跑跑翻译成机器指令
对应图片中红色框框起来的部分:
- 代码到 JVM 上的过程:Java 代码会被编译成 .class 文件
对应图片中绿色框框起来的部分:
- Java 的跨平台优势:Java 字节码(.class 文件)和 JVM 提供了跨平台
第二篇文章
在第二篇文章里面我们说了两个问题,对应图片中绿色框框起来的部分:
-
JVM 加载 class 字节码文件过程
-
类加载器和双亲委派模型(重点)
小结
通过前面两篇文章的讲解,已经把我们编写的.java 文件编译成 .class 字节码文件的过程讲清楚了,
然后 JVM 加载 .class 字节码文件的过程也讲清楚了。
接下来的文章我们就要深入 JVM 的内部,来讲一下它的内部工作机制等。
JVM 运行时数据区落地
JVM 运行时数据区的设计理念
说起 JVM 运行时数据区很多人都能背出来,比如堆、方法区、虚拟机栈等。如下图:
那你知道 JVM 运行时数据区为什么会这样设计吗?
设计理念
其实 JVM 虚拟机是参考物理机实现的,那我们的物理计算机的实现是遵循一个什么样的模型呢?计算机一般是按照下面这个模型实现的
这图大家学计算机的肯定都不陌生,这是冯·诺依曼结构。下面我就从冯·诺依曼结构推演出我们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 工作流程图,没事就可以拿出来看一看,然后自己可以对着这张图回想我们文章的内容。
如果有的内容我说的不够深入,大家也可以去深入学习一下。
面试的时候,面试官问到运行时数据区,大家也可以把这种设计理念说给面试官听,面试官会眼前一亮的,觉得你有研究。
预告
我们讲了运行时数据区的设计理念与落地,下一篇文件会说运行时数据区每一部分的作用,然后通过一个真实的代码案例,来讲解运行时数据区每一部分存储的是什么内容等。
共同学习,写下你的评论
评论加载中...
作者其他优质文章