JVM类加载机制

目录

一、Java为什么是一种跨平台的语言?

二、Java代码的执行流程

解释执行为主,编译执行为辅:

三、类加载的过程

3.1、加载

类加载器(就是加载类的)分为:

3.1.1、启动类加载器(Bootstrap ClassLoader):

3.1.2、扩展类加载器(Extension ClassLoader):

3.1.3、应用程序类加载器(Application ClassLoader):

双亲委派模型:

 3.2、验证

3.3、准备

3.4、解析

3.5、初始化

四、 主动引用

4.1、字节码指令

4.2、反射

4.3、父类加载

4.4、主类

4.5、接口的实现类

五、被动引用

六、对象的创建过程

6.1、类加载检查

6.2、分配内存

6.3、初始化零值

6.4、设置对象头

6.5、执行 init 构造方法


一、Java为什么是一种跨平台的语言?

通常,我们编写的java源代码会被JDK的编译器编译成字节码文件,再由JVM将字节码文件翻译成计算机读的懂得机器码进行执行;因为不同平台使用的JVM不一样,所以不同的JVM会把相同的字节码文件翻译成不同操作系统认识的机器码,这样就实现了跨平台;

二、Java代码的执行流程

解释执行为主,编译执行为辅:

JIT编译器:当虚拟机发现某个方法或代码块运行特别频繁时,就会把这些代码认定为(Hot Spot Code 热点代码,为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并保存到虚拟机内存中;

三、类加载的过程

3.1、加载

通过类的完全限定名称获取定义该类的二进制字节流。将该字节流表示的静态存储结构转换为Metaspace元空间区的运行时存储结构。在内存中生成一个代表该类的 Class 对象,作为元空间区中该类各种数据的访问入口。


类加载器(就是加载类的)分为:

3.1.1、启动类加载器(Bootstrap ClassLoader):

加载java核心类库,不继承ClassLoader,只加载包名为java,javax,sun开头的类;

3.1.2、扩展类加载器(Extension ClassLoader):

加载javax开头的扩展类库,继承自ClassLoader,父类加载器为启动类加载器,从java.ext.dirs指定的路径下加载类库;或者从JDK安装目录的jre/lib/ext目录下加载类库,如果用户自定义的jar包放在jre/lib/ext下,也会自动由扩展类加载器加载;

3.1.3、应用程序类加载器(Application ClassLoader):

加载用户自定义或者第三方jar包,继承自ClassLoader,父类加载器为扩展类加载器,负责加载环境变量classpath或系统属性java.class.path指定的类库,java中自己写的类都是由应用程序类加载器加载的,可以通过ClassLoader.getSystemClassLoader()方法获取该类加载器;


双亲委派模型:

一个类加载器首先将类加载请求转发到父类加载器,只有当父类加载器无法完成时才尝试自己加载。如果有人想替换系统级别的类:String.java。篡改它的实现,在这种机制下这些系统的类已经被Bootstrap classLoader加载过了,所以其他类加载器并没有机会再去加载,从一定程度上防止了危险代码的植入。 


 3.2、验证

这一阶段的主要目的是为了确保 Class 文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

3.3、准备

类变量是被 static 修饰的变量,准备阶段为类变量分配内存并设置初始值,使用的是元空间区的内存。初始值一般为 0 值。(如果类变量是常量,那么它将初始化为表达式所定义的值而不是 0。)

3.4、解析

将常量池的符号引用替换为直接引用的过程。其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。

3.5、初始化

初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>()方法的过程。在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。


四、 主动引用

4.1、字节码指令

jvm 执行 new指令时会加载类。即:当程序创建一个类的实例对象。

jvm 执行 getstatic指令时会加载类。即:程序访问类的静态变量(不是静态常量,常量会被加载到运行时常量池)。

jvm 执行 putstatic指令时会加载类。即:程序给类的静态变量赋值。

jvm 执行 invokestatic指令时会加载类。即:程序调用类的静态方法。

4.2、反射

使用 java.lang.reflect包的方法对类进行反射调用时如 Class.forname("..."), 或newInstance() 等等。如果类没初始化,需要触发类的加载。

4.3、父类加载

加载一个类,如果其父类还未加载,则先触发该父类的加载。

4.4、主类

当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main() 方法的类),虚拟机会先加载这个类。

4.5、接口的实现类

当一个接口中定义了 JDK8 新加入的默认方法(被 default 关键字修饰的接口方法)时,如果有这个接口的实现类发生了加载,则该接口要在实现类之前被加载。


五、被动引用

1,通过子类引用父类的静态字段,不会导致子类加载。

2,通过数组定义来引用类,不会触发此类的加载。该过程会对数组类进行加载,数组类是一个由虚拟机自动生成的、直接继承自 Object 的子类,其中包含了数组的属性和方法。

3,常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的加载。


六、对象的创建过程

6.1、类加载检查

虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

6.2、分配内存

类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。内存分配的查找方式“指针碰撞”“空闲列表” 两种。(选择以上两种方式中的哪一种,取决于 Java 堆内存是否规整。而 Java 堆内存是否规整,取决于 GC 收集器的算法是"标记-清除",还是"标记-整理"。)

6.3、初始化零值

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这一步操作保证了对象的实例字段在 Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

6.4、设置对象头

初始化零值完成之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。 这些信息存放在对象头中。 另外,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。

6.5、执行 init 构造方法

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从Java 程序的视角来看,对象创建才刚开始,<init> 构造方法还没有执行,目前所有的字段都还为零。所以一般来说,执行 new 指令之后会接着执行 <init> 构造方法,把对象按照程序逻辑的意愿进行初始化,这样一个真正可用的对象才算完整创建出来。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UMA 2 - Unity Multipurpose Avatar☀️三.给UMA设置默认服饰Recipes

文章目录 🟥 项目基础配置🟧 给UMA配置默认服饰Recipes🟨 设置服饰Recipes属性🟥 项目基础配置 将 UMA_DCS 预制体放到场景中创建空物体,添加DynamicCharacterAvatar 脚本,选择 HumanMaleDCS作为我们的基本模型配置默认Animator 🟧 给UMA配置默认服饰Recipes 服饰Re…

回归预测 | MATLAB实现PCA-BP主成分降维结合BP神经网络多输入单输出回归预测

回归预测 | MATLAB实现PCA-BP主成分降维结合BP神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现PCA-BP主成分降维结合BP神经网络多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现PCA-BP主成分降维算法结合BP神经网络多输入单输出回…

【数据结构】串

串 串的顺序实现简单的模式匹配算法KMP算法KMP算法的进一步优化 串的顺序实现 初始化 #define MaxSize 50 typedef char ElemType;//顺序存储表示 typedef struct{ElemType data[MaxSize];int length; }SString;/*** 初始化串*/ void InitString(SString *string) {for (int …

Cmake入门(一文读懂)

目录 1、Cmake简介2、安装CMake3、CMakeLists.txt4、单目录简单实例4.1、CMakeLists.txt4.2、构建bulid内部构建外部构建 4.3、运行C语言程序 5、多目录文件简单实例5.1、根目录CMakeLists.txt5.2、源文件目录5.3、utils.h5.4、创建build 6、生成库文件和链接外部库文件7、注意…

Mysql5.7(Docker环境)实现主从复制

文章目录 前言一、MySQL主从数据库同步如何实现&#xff1f;(理论)1.1 为什么要使用数据库主从1.2 数据库主从实现原理是什么&#xff1f; 二、Docker环境配置MySQL5.7主从(实践)2.1 配置安装Master2.2 配置安装Slave 前言 本文章将以MySQL5.7版本来讲诉MySQL主从复制的原理以…

【计算机网络】UDP数据包是如何在网络中传输的?

List item 创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 更多计算机网络知识专栏&#xff1a;计算机网络&#x1f525;…

【uni-app】

准备工作&#xff08;Hbuilder&#xff09; 1.下载hbuilder&#xff0c;插件使用Vue3的uni-app项目 2.需要安装编译器 3.下载微信开发者工具 4.点击运行->微信开发者工具 5.打开微信开发者工具的服务端口 效果图 准备工作&#xff08;VScode&#xff09; 插件 uni-cr…

Android窗口层级(Window Type)分析

前言 Android的窗口Window分为三种类型&#xff1a; 应用Window&#xff0c;比如Activity、Dialog&#xff1b;子Window&#xff0c;比如PopupWindow&#xff1b;系统Window&#xff0c;比如Toast、系统状态栏、导航栏等等。 应用Window的Z-Ordered最低&#xff0c;就是在系…

Codeforces Round 827 (Div. 4) D 1e5+双重for循环技巧

Codeforces Round 827 (Div. 4) D 做题链接&#xff1a;Codeforces Round 827 (Div. 4) 给定一个由 n个正整数 a1,a2,…,an&#xff08;1≤ai≤1000&#xff09;组成的数组。求ij的最大值&#xff0c;使得ai和aj共质&#xff0c;否则−1&#xff0c;如果不存在这样的i&#…

Jetsonnano B01 笔记3:GPIO上拉下拉-输入输出读取

今日继续我的jetsonnano学习之路&#xff0c;今日学习的是GPIO的上拉下拉&#xff0c;输入输出的读取&#xff0c;文章贴出完整操作步骤过程&#xff0c;贴出源码。 目录 Linux常用文件命令&#xff1a; ls&#xff08;list&#xff09;列表&#xff1a; man&#xff1a; …

页面页脚部分CSS分享

先看效果&#xff1a; CSS部分&#xff1a;&#xff08;查看更多&#xff09; <style>body {display: grid;grid-template-rows: 1fr 10rem auto;grid-template-areas: "main" "." "footer";overflow-x: hidden;background: #F5F7FA;min…

【微服务】五. Nacos服务注册

Nacos服务注册 5.1 Nacos服务分级存储模型Nacos服务分级存储模型&#xff1a;服务集群属性&#xff1a;总结&#xff1a; 5.2 根据集群负载均衡总结 5.3 Nacos服务实例的权重设置总结&#xff1a; 5.6 环境隔离namespace总结 5.7 Nacos和Eureka的对比总结 5.1 Nacos服务分级存储…

科技云报道:AI时代,对构建云安全提出了哪些新要求?

科技云报道原创。 随着企业上云的提速&#xff0c;一系列云安全问题也逐渐暴露出来&#xff0c;云安全问题得到重视&#xff0c;市场不断扩大。 Gartner 发布“2022 年中国 ICT 技术成熟度曲线”显示&#xff0c;云安全已处于技术萌芽期高点&#xff0c;预期在2-5年内有望达到…

Material Design系列探究之LinearLayoutCompat

谷歌Material Design推出了许多非常好用的控件&#xff0c;所以我决定写一个专题来讲述MaterialDesign&#xff0c;今天带来Material Design系列的第一弹 LinearLayoutCompat。 以前要在LinearLayout布局之间的子View之间添加分割线&#xff0c;还需要自己去自定义控件进行添加…

自动驾驶多任务框架Hybridnets——同时处理车辆检测、可驾驶区域分割、车道线分割模型部署(C++/Python)

一、多感知任务 在移动机器人的感知系统&#xff0c;包括自动驾驶汽车和无人机&#xff0c;会使用多种传感器来获取关键信息&#xff0c;从而实现对环境的感知和物体检测。这些传感器包括相机、激光雷达、雷达、惯性测量单元&#xff08;IMU&#xff09;、全球导航卫星系统&am…

SpringCloud(二)

1.Nacos配置管理 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我们需要一种统一配置管理方案&#…

NIFI实现数据库数据增量同步

说明 nifi版本&#xff1a;1.23.2&#xff08;docker镜像&#xff09; 需求背景 将数据库中的数据同步到另一个数据库中&#xff0c;要求对于新增的数据和历史有修改的数据进行增量同步 模拟数据 建表语句 源数据库和目标数据库结构要保持一致&#xff0c;这样可以避免后…

固定资产管理数据怎么算?

在企业的运营中&#xff0c;固定资产的管理是一个至关重要的环节。然而&#xff0c;对于许多企业来说&#xff0c;理解和管理这些资产的数据却常常是一团迷雾。那么&#xff0c;固定资产管理数据究竟应该如何计算呢&#xff1f;这是一个需要我们深入探讨的问题。  我们需要明…

MySQL——命令行客户端的字符集问题

原因&#xff1a;服务器端认为你的客户端的字符集是utf-8&#xff0c;而实际上你的客户端的字符集是GBK。 查看所有字符集&#xff1a;SHOW VARIABLES LIKE character_set_%; 解决方案&#xff0c;设置当前连接的客户端字符集 “SET NAMES GBK;”

Android12之/proc/pid/status参数含义(一百六十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…