【JVM】- 运行时数据区

一、什么是JVM

JVM是整个java实现跨平台的最核心的部分,能够运行以Java语言写的程序。java语言“一次编译,到处运行”,正是由于jvm的存在,才得以实现。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码文件),就可以在多种平台上不加修改地运行。而一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。

二、JVM功能

1、软件层面,将字节码文件翻译成机器吗执行
我们写的代码在机器上运行,机器只认识机器指令0和1(量子计算机还有其他中间状态)。运行代码时,java会生成一个平台无关的字节码class文件(一次编译,到处运行),JVM会读取class文件丢到机器上运行,需要转换成机器指令
2、自动内存管理,c语言需要手动管理
内存分配、垃圾回收,JVM会在底层完成,让程序员专注于业务代码。这样我们用的时候只需要new创建,不用关心什么时候回收。

三、JVM运行时数据区

图示
在这里插入图片描述在这里插入图片描述
由上图可知,运行时数据分为五块,程序计数器、虚拟机栈、本地方法栈是线程私有的,方法区、堆是线程共享的。

1、程序计数器
程序计数器的作用是指向当前线程正在执行的字节码指令的地址、行号。
问什么需要存储呢?因为线程是方法执行的最小单位,cpu执行线程时是任务调度的方式,如果时间片轮到下一个线程,那么低昂前线程就需要挂起,挂起后为方便下一次获取时间片可以继续运行,所以需要记录本地执行的字节码指令的地址和行号。

2、虚拟机栈
虚拟机栈存储当前线程运行方法所需要的数据、指令、返回地址
虚拟机栈中存储的基本单位是栈帧,前边我们提到虚拟机栈是线程私有的,所以线程中的一个方法对应一个栈帧。执行方法时需要压栈。而且一个方法执行时,不是只压入一个栈,依赖的方法也是独立的栈帧。
每个栈帧中有多个区域,我们重点关注四个区域:
在这里插入图片描述
2.1、局部变量表
存储方法参数和方法内部定义的局部变量,局部变量包括基本类型和引用类型
局部变量表的容量以变量槽(Variable Slot,下称Slot)为最小单位,单位大小虽然没有明确规定,一个slot可以存放一个32位的数据类型,64位需要对齐
而局部变量表的最大容量在编译为class文件时就已确定

2.2、操作数栈
是一个后入先出的栈,当一个方法刚刚开始的时候,这个方法的操作数栈是空的,在方法的执行过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是入栈和出栈操作。

2.3动态链接
在 Class 文件里面,描述一个方法调用了其他方法,或者访问其成员变量是通过符号引用来表示的。这些符号引用一部分会在类加载阶段或者第一次使用的时候就转化为直接引用,这种转化称为静态解析。另外一部分将在每一次运行期间转化为直接引用,这部分称为动态连接
比如我们注入一个service,调用方法时,会有多态性,具体是哪个实现类的哪个方法在编译器是无法确定的,只有在真正的调用的时候,才知道具体的方法。

3、本地方法栈
本地方法栈的结构和功能和虚拟机栈一样,只不过本地方法栈中存放的Native修饰的方法。

4、方法区
JDK1.7之前,方法区的实现为永久代,1.8对方法区的实现变为了元空间
1.8后方法区存放着运行时常量区,而运行时常量区包含类的各种加载信息、常量、静态变量等。

4.1运行时常量池
jvm虚拟机在完成类装载操作后,将class文件中的常量池载入到内存中,并保存在运行时常量区,就是我们常说的常量池。

除了是静态常量池里的内容外,还将静态常量池里的符号引用转变为直接引用,比如说类的静态方法或私有方法,实例构造方法,父类方法,这是因为这些方法不能被重写其他版本,所以能在加载的时候就可以将符号引用转变为直接引用,而其他的一些方法是在这个方法被第一次调用的时候才会将符号引用转变为直接引用的。

5、堆
Java堆是虚拟机所管理的内存中最大的一块,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这块区域是“线程共享”的。
Java堆是垃圾收集器管理的主要区域,因此也被称作“GC堆”。由于现在垃圾收集器基本采用分代收集算法,所以Java堆还可以细分为新生代和老年代。Java堆可以处于物理上不连续的内存空间中,只要逻辑上连续即可。如果堆中没有内存完成实例分配,并且堆也无法扩展时,将会抛出OutOfMemoryError异常。具体的我们会在下篇博文中介绍。

jdk1.8的堆中还有一种常量池是字符串常量池字符串常量池在JDK1.7之前,存放在方法区的运行时常量区,JDK1.7字符串常量池拿到了堆中。
字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到string pool中(记住:string pool中存的是引用值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的)。

四、静态常量池

常量池除了运行时常量池、字符串常量池,还有一种是静态常量池。
静态常量池存在于class字节码文件中,包括字面量和符号引用:
i) 字面量
One. 文本字符串
Two. 声明为final的常量
Three. 基本数据类型的值
ii) 符号引用量:java虚拟机在执行指令的时候会依赖这些信息
One. 类和接口的全限定名
Two. 字段名称和描述符
Three. 方法名称和描述符

----------------------------------有不正确的望各位指正。-----------------------------------------------

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子松的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值