JVM之加载class文件

1.JVM相关概念

官网地址:Java Platform Standard Edition 8 Documentation (oracle.com)

jvm: java虚拟机,是java程序的运行环境(java二进制字节码的运行环境)

jre:jvm+基础类库(java.lang包下工具类、IO、集合类库、线程类等)组成了完整的运行环境

jdk:是由jvm+jre+编译工具(javac、javap等)组成,它是开发人员开发、测试时的一个工具包。

2.HotSpot JVM架构

hotspot目前是最常用的jvm架构,可以通过java -version查看,其架构图如图所示:

由图中可以看出JVM结构主要分为三大模块:

a.class Loader SubSystem 类加载

b Runtime Data Areas 运行时数据区  又包含 方法区、堆栈、java虚拟机栈、程序计数器、本地方法栈

c.Execution Engine 执行引擎  又包含JIT 即时编译器 、垃圾回收器

2.1 Class File

程序员写的程序都是.java文件,而JVM是加载class文件的,那么第一个问题,如何将java文件转换为jvm加载的class文件呢?使用jdk自带的编译工具javac就可以将.java文件编译为.class文件,javac的编译过程主要是整合编译原理、C语言、java语言进行一系列的词法分析、语法树生成、字节码生成等等

比如我们将一段java代码编译成class文件后,class文件的内容都是16进制表示的字节码

该字节码对应的内容信息可参考官网:Chapter 4. The class File Format (oracle.com)

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

举例分析:  比如u4就代表无符号位4字节 也就是对应上面16进制class文件中的前8位(2个为1个字节,1个字节为8bit,1位16进制数为4bit)

magic对应cafebabe。带着magic在官网上搜索。可以看到这么一句话: The magic item supplies the magic number identifying the class file format。代表的是这是一个class文件的标记

按上述方法,依次查找,就可以手动解析出整个class文件对应的含义。

当然,也可以采用jdk自带的反汇编命令javap对class文件进行反编译,就可以直接查看字节码信息和指令等信息

javap ‐v ‐c ‐p User.class > User.txt 进行反编译,查看字节码信息和指令等信息

3. 类加载机制

从第2节我们了解到了class文件的生成以及如何解读,那么有了class文件,CPU想要运行我们的程序,我们首先就需要把class文件以二进制的形式加载到内存中的一片物理地址中,那么JVM首先要做的就是类加载。类加载又分为3部分,Loading装载、Linking链接、Initialization初始化

官网:Chapter 5. Loading, Linking, and Initializing (oracle.com)

3.1 Loading

Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation。

说人话就是:装载就是把类和接口名以二进制的形式表示出来

加载的顺序是由顶向下:主要分为几部分 a.jre自带的一些基础jar包的加载(bootStrap加载器负责);b.java平台扩展的一些jar包;c.java应用中指定的jar包,可以理解为就咱们自己写的一些类;d.自定义的class。

问题: 假如说bootStrap已经加载了java.lang.String。而我们App ClassLoader也用到了App ClassLoader那么这个类如果被加载了两遍,就会出现new对象时找不到引用哪个的问题。因此,双亲委派机制就诞生了。双亲委派机制主要就是为了检查某个类是否已经加载了。

自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个Classloader已加 载,就视为已加载此类,保证此类只所有ClassLoader加载一次。

3.2 Linking

a. 首先保证被加载类的正确性

b.为类或接口的静态变量分配内存,并将其初始化为默认值(比如 private static int a = 10  会先将a初始化为0)

c. 将运行时常量池中的符号引用(指的是16进制的class文件中的常量池的一些16进制表示)转换为直接引用(物理内存中的一段地址) 

3.3 Initialization

对类的静态变量,静态代码块执行初始化操作(a = 10)

4.运行时数据区

 JVM通过类加载器将类信息,静态变量等信息加载到了内存中,那么java真正运行的时候还有方法、局部变量等信息,这些信息就会存储在运行时数据区中。运行时数据区可以以两个维度来划分进程生命周期(线程共享 全局变量)和线程生命周期 (局部变量)

方法区和堆栈都属于是进程生命周期,所有线程共享;java虚拟机栈、程序计数器、本地方法栈是线程生命周期(也就是线程安全的不存在并发问题)

官网地址:Chapter 2. The Structure of the Java Virtual Machine (oracle.com)

4.1Method Area(方法区)

方法区是各个线程共享的内存区域,在虚拟机启动时创建,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码(这个可以理解为代码中经常被使用的Util工具类)等数据。当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

4.2 Heap(堆)

a.java堆是java虚拟机所管理内存中最大的一块,在虚拟机启动时创建,被所有线程共享

b.Java对象实例以及数组都在堆上分配

c.堆内存空间不足时,也会抛出OOM

JVM为了提高性能和内存开销,在堆中还分配了一分内存空间存储字符串,也就是字符串常量池,下图举例说明了字符串的存储方式。

代码验证:

public class SCPDemo {
public static void main(String[] args) {
String str1="Jack"; // 这个常量一定会放到字符串常量池中
String str2="Jack";
String str3=new String("Jack");
String str4=str3.intern(); // 找字符串常量池中是否有该常量,如果有就直接返回,如果没有再创建
// equals 只会比较值 == 会比较地址
System.out.println(str1.equals(str2)); // true
System.out.println(str1==str2); // true
System.out.println(str1.equals(str3)); // true
System.out.println(str1==str3); // false
System.out.println(str1.equals(str4)); // true
System.out.println(str1==str4); // true
}
}

4.2.1 java对象内存布局

一个对象在内存中包括3个部分 对象头、实例数据和对齐填充。举个例子,假设我们有一个Student类,那么该类在内存中占多大内存呢?

class Student{
    private double salary;
    private Object obj;
}

实例对象占用8+8 = 16 对象头 8+8+4 20 对齐填充为8字节的整数倍 因此该对象占用40字节的内存空间

4.2.2 方法区引用指向堆

4.2.3 堆指向方法区

4.3 Java Virtual Machine Stacks(Java虚拟机栈)

a. 虚拟机栈是一个线程执行的区域,保存着一个线程中方法的调用状态。换句话说,一个Java线程的运行状态,由一个虚拟机栈来保存,所以虚拟机栈肯定是线程私有的,独有的,随着线程的创建而创建。

b.每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧。调用一个方法,就会向栈中压入一个栈帧;一个方法调用完成,就会把该栈帧从栈中弹出。

代码示例:

void a(){
}
void b(){
}
void c(){
}

流程图:

每一个栈帧中的局面变量表如果有实例对象引用,则指向堆内存

4.4 本地方法栈

4.5 The PC Register

如果线程正在执行java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址。如果正在执行的是Native方法,则这个计数器为空。

5.总结

       一个java程序的执行,首先经历编译阶段由.java文件编译为16进制class文件并存放在磁盘或IO设备中,然后JVM可以适用于各个操作系统,将class文件编译为CPU可以运行的二进制文件。JVM首先会经过类加载器,将类名接口名、静态变量、常量等进行初始化并加载到内存中用二进制表示,存储在运行时数据区的方法区中,java代码中的实例对象,全局变量,字符串常量等存储在堆栈中,线程共享;java虚拟机栈为java中的具体线程执行,会以栈结构存储每一个方法,每一个方法都是用栈帧来表示,栈帧中包含了局部变量、操作数栈、动态链接和调用完成,局部变量若有实例引用则指向堆栈,动态链接为指向本地方法栈;本地方法栈则主要指向native方法;程序计数器记录的则是正在执行java方法的虚拟机字节码的地址,若是native方法,则计数器为空。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/660449.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ElementUI之el-table标题列中显示el-tooltip

ElementUI之el-table标题列中显示el-tooltip 文章目录 ElementUI之el-table标题列中显示el-tooltip1. el-table标题列中显示el-tooltip2. 实现代码3. 展示效果 1. el-table标题列中显示el-tooltip 在el-table-column标签内添加具名插槽v-slot:header 在el-tooltip标签中使用具…

AI企业需要“联盟营销”?一文带你探索AI企业营销新玩法!

为什么联盟营销对AI业务有较大优势 联盟营销在电商领域、saas领域与其他产品领域同样有效。在AI业务中,它有效的原因与其他领域大不相同。 高好奇心和试用率 AI领域是创新的热点。它吸引了一群渴望探索和尝试每一项新技术的人群。这种蓬勃的好奇心为聪明的AI企业提…

NTP服务的DDoS攻击:原理和防御

NTP协议作为一种关键的互联网基础设施组件,旨在确保全球网络设备间的时钟同步,对于维护数据一致性和安全性至关重要。然而,其设计上的某些特性也为恶意行为者提供了发动大规模分布式拒绝服务(DDoS)攻击的机会。以下是NTP服务DDoS攻击及其防御…

34岁嵌入式开发工程师的出路在哪儿?

作为一个从事智能穿戴行业11年的资深从业者,您积累了丰富的技术和经验,IT行业内有很多发展机会和出路可以选择,以下是一些建议供参考:刚好我有一些资料,是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到…

uniapp开发vue3监听右滑返回操作,返回到指定页面,解决边缘区域监听错误问题

想要在uniapp框架中监听左滑或者右滑手势,需要使用touchstart和touchend两个api,因为没有原生的左右滑监听api,所以我们只能依靠这两个api来获取滑动开始时候的x坐标和滑动结束后的x坐标做比对,右滑的话,结束时候的x坐…

gitea的git库备份与恢复

文章目录 gitea库的备份与恢复概述笔记实验环境更新git for windows更新 TortoiseGit备份已经存在的gitea的git库目录使用gitea本身来备份所有git库目录将gitea库恢复到新目录m1m2m3启动gitea - 此时已经恢复完成FETCH_HEAD 中有硬写位置再查一下app.ini, 是否改漏了。m1m2 总结…

pytorch深度学习-环境搭建-2

1.1下载cudnn,解压 1.2.找到本级cuda安装路径 1.3.刚才解压文件复制到cuda安装目录 2.1 安装pytouch conda install pytorch torchvision torchaudio pytorch-cuda12.1 -c pytorch -c nvidia 3.pytouch验证 我这儿是有问题的 PS C:\Users\Administrator\PycharmProjects\pyth…

BGP路由策略实验

一、实验拓扑 二、IP分配(骨干) R1: 0/0/0 15.0.0.1 24 0/0/1 18.0.0.2 24 0/0/2 19.0.0.1 24 R2: 0/0/0 16.0.0.1 24 0/0/1 15.0.0.2 24 R3: 0/0/0 17.0.0.2 24 0/0/1 18.0.0.1 24 R4: 0/0/0 16.0…

怎么将3D模型转换立面图---模大狮模型网

在建筑设计、室内设计以及产品建模等领域,经常需要将3D模型转换为立面图以进行展示、分析或交流。立面图能够清晰地呈现物体的外观和结构,是设计和施工中不可或缺的一部分。 一、导出3D模型 首先,需要将3D模型导出为CAD软件能够识别的格式。…

零基础学习图生图

目录 一、图生图是什么二、安装秋叶整合包2.1 秋叶包安装2.2 秋叶包拓展安装:2.3 ckpt配置:2.4 界面常用功能配置: 三、图生图基本功能展示3.1 图生图的界面3.2 重要的参数设置:3.3 涂鸦功能3.4 局部重绘功能3.5 涂鸦重绘3.6 上传…

microk8s 报错tls: failed to verify certificate: x509:

问题: ssh命令出现如下图所示 输入任何microk8s的容器命令几乎都是x509报错 kubectl get pods -ALL 原因: 证书过期 相关文档: MicroK8s - 服务和端口 Microk8S v1.24 - refresh-certs 似乎无法刷新证书 问题 #3241 规范/microk8s Git…

二叉树介绍及堆

文章目录 树 概念及结构 二叉树 概念及结构 特殊的二叉树 完全二叉树 满二叉树 性质 储存 顺序存储 链式储存 堆 概念及结构 小堆 大堆 建堆 向上调整建堆 向下调整建堆 TOPK问题 法一: 法二: 树 概念及结构 树是一种非线性的数据…

[图解]企业应用架构模式2024新译本讲解02-表数据入口

1 00:00:00,420 --> 00:00:04,330 这个案例,我们就是用书上的案例了 2 00:00:06,080 --> 00:00:08,860 收入确认的一个案例 3 00:00:09,510 --> 00:00:11,100 书上讲了,收入确认 4 00:00:13,330 --> 00:00:15,270 就是说,你给…

5月岚庭工人大会“安全就是效率、形象即是品质”

2024年5月18日、19日岚庭一月一期的“产业工人大会”和“工程大会”圆满举行初夏正当时,此次大会主要围绕“安全”与“形象”展开六场专题培训只为精益求精产业工人和装修管家全体到场。 岚庭 以绝对【安全】护家护园 安全就是生命,违章就是事故&#x…

Javaweb基础之Filter

大家好,这里是教授.F 引入: 为什么需要过滤器???我们在访问一个项目的时候,常常有很多页面,如果没有过滤器,则我们需要在用户访问一个页面的时候,都要进行一个校验&…

OrangePi AIpro 快速上手初体验——接口、样例和目标检测

​ 一、 开发板简介 OrangePi AIpro开发板是香橙派联合华为精心打造的高性能 AI 开发板,其搭载了昇腾 AI 处理器,可提供 8TOPS INT8 的计算能力,内存提供了 8GB 和 16GB两种版本。可以实现图像、视频等多种数据分析与推理计算,可…

合约之间调用-如何实现函数静态调用?

合约之间的函数调用 EOA,external owned account,外部账号,例如metamask调用最终总是由EOA发起的合约之间的调用使得一次完整的调用成为一个调用链条 合约间调用过程 调用者须持有被调用合约的地址得到被调用合约的信息将地址重载为被调用合…

母亲的爱与妻子的爱,同为“爱“。不同感受!

母亲的爱与妻子的爱,虽然都是一个女人给予男人的爱,却有着本质的不同! 天下父母对儿女的爱大多相同。在母亲眼中,儿女无论是多大年龄,无论你是否长大成人,也无论你做多大的官,有多么大的成就&am…

【深度学习】吸烟行为检测软件系统

往期文章列表: 【YOLO深度学习系列】图像分类、物体检测、实例分割、物体追踪、姿态估计、定向边框检测演示系统【含源码】【深度学习】YOLOV8数据标注及模型训练方法整体流程介绍及演示【深度学习】行人跌倒行为检测软件系统【深度学习】火灾检测软件系统【深度学…

KDD 2024|基于隐空间因果推断的微服务系统根因定位

简介:本文介绍了由清华大学、南开大学、eBay、微软、中国科学院计算机网络信息中心等单位共同合作的论文《基于隐空间因果推断的受限可观测性场景的微服务系统根因定位》。该论文已被KDD 2024会议录用。 论文标题:Microservice Root Cause Analysis Wit…