JVM篇之类加载机制

news2024/11/28 0:33:06

目录

      • JVM篇之类加载机制
        • 类加载过程
          • 1.加载
          • 2.验证
          • 3.准备
          • 4.解析
          • 5.初始化
        • 类加载器
        • 类的加载
        • 双亲委派模型

JVM篇之类加载机制

类加载过程

JVM类的加载过程分为五个部分:加载,验证,准备,解析,初始化,其中验证,准备,解析三个部分统称为连接。如下图所示

在这里插入图片描述

1.加载
  1. 通过一个类的全限定名来获取其定义的二进制字节流,将二进制数据读入内存,放入运行时数据区的方法区中。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  3. 在堆区创建一个代表这个类的java.lang.Class对象,用来封装类在方法区内的数据结构,作为对方法区中这些数据的访问入口。

我的理解:加载的最终结果是在堆中创建了一个Class对象,这个对象是独一无二的。
Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。
具体关于Class对象的内容可以查看反射相关内容。

class Car{

}
public class Loading {
    public static void main(String[] args) {
        Car car1 = new Car();
        Car car2 = new Car();
        Car car3 = new Car();

        Class<? extends Car> car1Class = car1.getClass();
        Class<? extends Car> car2Class = car2.getClass();
        Class<? extends Car> car3Class = car3.getClass();

        System.out.println("car1:"+car1 +" car2:"+car2 +" car3:"+car3);//car1:Car@15aeb7ab car2:Car@7b23ec81 car3:Car@6acbcfc0
        System.out.println("car1Class:"+car1Class +"; car2Class:"+car2Class +"; car3Class:"+car3Class);//car1Class:class Car; car2Class:class Car; car3Class:class Car
        System.out.println(car1Class==car2Class);//true
        System.out.println(car1Class.getClass());//class java.lang.Class
    }
}

我的理解:java中最抽象的类是java.lang.Class,而Car类对象(car1Class)可以看作是java.lang.Class类的一个实例化对象
与此相对应的,我们可以把car1对象看作是Car类的一个实例化对象。堆的唯一目的就是存放对象实例。

加载.class文件的方式

  1. 将Java源文件动态编译为.class文件
  2. 从zip压缩包读取,成为日后jar ,war格式的基础
  3. 从本地系统中直接加载
    • Class findSystemClass(String name): 方法从本地文件系统装入文件。它在本地文件系统中寻找类文件,如果存在,就使用 defineClass 将原始字节转换成 Class 对象,以将该文件转换成类。
  4. 通过网络下载.class文件
  5. 从专有数据库中提取.class文件
2.验证

确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。大概分为4个阶段的检验动作:

  1. 文件格式验证:验证字节流是否符合Class文件格式的规范;例如:是否以 0xCAFEBABE开头、主次版本号是否在当前虚拟机的处理范围之内、常量池中的常量是否有不被支持的类型。

  2. 元数据验证:对字节码描述的信息进行语义分析(注意:对比javac编译阶段的语义分析),以保证其描述的信息符合Java语言规范的要求;例如:这个类是否有父类,除了 java.lang.Object之外。

  3. 字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。

  4. 符号引用验证:确保解析动作能正确执行。

验证阶段是非常重要的,但不是必须的,它对程序运行期没有影响,如果所引用的类经过反复验证,那么可以考虑采用 -Xverifynone参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。

3.准备

准备阶段是正式为类的静态变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。

注意:

  1. 只会为被static关键字修饰的静态成员变量设置初始值
    • 可以来思考一下为什么:静态成员变量可以通过类名直接调用,因此应该先于类的实例化设置初始值。
  2. 这里所设置的初始值如果不被final修饰,则是数据类型默认的零值(如0、0L、null、false等),而不是被在Java代码中被显式地赋予的值。
  3. 对final的静态字面值常量直接赋初值,即字面值

例如:

public static int a=100;//准备阶段设为0
public static final int b=100;//准备阶段设为100
4.解析

把类中的符号引用转换为直接引用
在编译时,java类并不知道引用类的实际地址,所以用符号引用来代替。在该阶段转换为实际内存地址。

5.初始化

初始化主要完成静态块执行以及静态变量的赋值.
先初始化父类,再初始化当前类.
只有对类主动使用时才会初始化.

触发初始化的条件有:

  1. 创建类的实例时
  2. 访问类的静态方法或静态变量的时候
  3. 使用Class.forName反射类的时候
  4. 或者某个子类初始化的时候

JVM初始化步骤

  1. 假如这个类还没有被加载和连接,则程序先加载并连接该类
  2. 假如该类的直接父类还没有被初始化,则先初始化其直接父类
  3. 假如类中有初始化语句,则系统依次执行这些初始化语句

类加载器

虚拟机设计团队把加载动作放到 JVM 外部实现,以便让应用程序决定如何获取所需的类,JVM 提
供了 3 种类加载器:启动类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)、应用程序类加载器(Application ClassLoader)。如下图所示:

在这里插入图片描述

先看一个例子

class Car{
    
}
public class Loading {
    public static void main(String[] args) {
        Car car = new Car();
        ClassLoader classLoader1 = car.getClass().getClassLoader();
        
        System.out.println(classLoader1);
        System.out.println(classLoader1.getParent());
        System.out.println(classLoader1.getParent().getParent());

    }
}

运行结果

jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
jdk.internal.loader.ClassLoaders$PlatformClassLoader@4eec7777
null

java9开始,将Bootstrap ClassLoader—>Platform ClassLoader
PlatformClassLoader的父类是null的原因:BootstrapClassLoader是用c语言实现的。

应用程序都是由这三种类加载器互相配合进行加载的,如果有必要,我们还可以加入自定义的类加载器。因为JVM自带的ClassLoader只是懂得从本地文件系统加载标准的java class文件,因此如果编写了自己的ClassLoader,便可以做到如下几点:

  1. 在执行非置信代码之前,自动验证数字签名。
  2. 动态地创建符合用户特定需要的定制化构建类。
  3. 从特定的场所取得java class,例如数据库中和网络中。

类的加载

类加载有三种方式:

  1. 命令行启动应用时候由JVM初始化加载
  2. 通过Class.forName()方法动态加载
  3. 通过ClassLoader.loadClass()方法动态加载

Class.forName()和ClassLoader.loadClass()区别

  • Class.forName():将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块;
  • ClassLoader.loadClass():只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
  • Class.forName(name,initialize,loader)带参函数也可控制是否加载static块。

双亲委派模型

双亲委派模型的工作流程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

优点:

  1. 避免类的重复加载
  2. 避免Java的核心API被篡改

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

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

相关文章

通用数据类型链表C语言实现

通用链表是一种动态内存分配的数据结构&#xff0c;其中每个节点包含一个指向下一个节点的指针和一个指向任意类型数据的指针。因此&#xff0c;通用链表可以容纳任意类型的数据&#xff0c;这是其与其他数据结构不同的地方。 通用链表的实现可以分为以下几个步骤&#xff1a;…

《百万在线 大型游戏服务端开发》前两章概念笔记

第1章 从角色走路说起 游戏网络通信的流程则是服务端先开启监听&#xff0c;等待客户端的连接&#xff0c;然后交互操作&#xff0c;最后断开。 套接字 每个Socket都包含网络连接中一端的信息。每个客户端需要一个Socket结构&#xff0c;服务端则需要N1个Socket结构&#xff…

直击2023云南移动生态合作伙伴大会,聚焦云南移动的“价值裂变”

作者 | 曾响铃 文 | 响铃说 2023年3月2日下午&#xff0c;云南移动生态合作伙伴大会在昆明召开。云南移动党委书记&#xff0c;总经理葛松海在大会上提到“2023年&#xff0c;云南移动将重点在‘做大平台及生态级新产品&#xff0c;做优渠道转型新动能&#xff0c;做强合作新…

利用canvas给图片添加水印

前言前两天给个人网站添加了一个小功能&#xff0c;就是在文章编辑上传图片的时候自动给图片加上水印。给网页图片添加水印是个常见的功能&#xff0c;也是互联网内容作者保护自己版权的方法之一。本文简单记录一下借助canvas在前端实现图片添加水印的实现方法。canvas元素其实…

学python的第七天---基础进阶

一、数组翻转写法一&#xff1a;myselfa[:size]a[:size][::-1]写法二&#xff1a;函数写法三&#xff1a;二、复制数组写法一:写法二&#xff1a;写法三&#xff1a;三、最小公倍数写法一&#xff1a;写法二&#xff1a;写法三&#xff1a;gcd写法四&#xff1a;其他&#xff1…

visual studio 2019创建一个项目的详细步骤

引言&#xff1a;本着边学边记录的原则&#xff0c;把学习的过程给记录下来&#xff0c;自己回顾的同时也分享给大家&#xff0c;转载请注明出处哈。 1、首先在桌面上双击打开visual studio 2019&#xff0c;看到如下界面&#xff1a; 2、点击1红框中的创建新项目&#xff0c;…

[hive]执行计划

https://www.bilibili.com/video/BV1g84y147sX/?p126&spm_id_from333.1007.top_right_bar_window_history.content.click&vd_source51f694f71c083955be7443b1d75165e0一、概述Explain呈现的执行计划&#xff0c;由一系列Stage组成&#xff0c;这一系列Stage具有依赖关…

Easy Deep Learning——全连接层

什么是全连接层?它的作用是什么? 我们还是回到之前的草地场景中,假设现在的问题变成让机器判断该草地上是不是有一只猫存在,由于之前做的卷积操作,将草地分成了许多网格,如果场地上只有一只猫,那么只有一个网格是有猫的,而其他的网格都不存在猫,一个卷积核运算可以得到…

java-泛型介绍

介绍 泛型是jdk5的时候出现的一种特性&#xff0c;可以在编译阶段约束操作的数据结构&#xff0c;并进行检查。 泛型只能用引用数据类型&#xff0c;如果是基本数据类型得使用包装类。 如ArrayList中的toArray(T[] a),是不可用转换为int[]的只能转换为Integer[] 好处 统一了…

Mysql的数据存储

Mysql的数据存储 对于mysql而言&#xff0c;数据是存储在文件系统中的&#xff0c;不同的存储存储引擎会有不同的文件格式和组织形式 1、InnoDB数据存储 InnoDB存储格式由大到小&#xff1a;表空间 → 段 → 区 → 页 → 行 对于innodb而言&#xff0c;数据是存储在表空间&…

linux系统整理一些工作中常用关于用户,用户组以及文件权限操作的相关命令

文章目录问题&#xff1a;前言&#xff1a;用户和用户组概念前言一、用户前言二、用户组一、添加用户和用户组二、查看用户所属组命令、三、管理用户组方法一、gpasswd命令方式二、newgrp命令方式三、usermod命令用户组实战&#xff1a;赋予用户root权限四、文件修改权限命令ch…

数字孪生与 UWB 技术创新融合:从单点测量到全局智能化

人员定位是指利用各种定位技术对人员在特定场所的位置进行准确定位的技术。人员定位技术主要应用于需要实时监控、管理和保障人员安全的场所&#xff0c;如大型厂区、仓库、医院、学校、商场等。人员定位技术的应用范围非常广泛&#xff0c;例如&#xff1a;-在工厂生产线上&am…

服务器Nginx安装实战

因为Vue项目发布在Tomcat中出现跨域为&#xff0c;所以需要Nginx进行反向代理&#xff0c;所以特此在云服务器中安装Nginx&#xff0c;本文章记录安装过程及解决安装过程中的错误处理。 一、Nginx 安装 登录服务器后&#xff0c;执行命令 yum info gcc-c pcre pcre-devel zl…

keras lstm

keras lstm的参数&#xff08;1&#xff09;units&#xff1a;LSTM层的单元个数&#xff0c;即LSTM网络中隐藏节点的数量。&#xff08;2&#xff09;activation&#xff1a;激活函数&#xff0c;用于更新内部状态的函数&#xff08;即门的决策函数&#xff09;。&#xff08;3…

dotConnect Universal 4.0.134 Crack

dotConnect Universal 能够呈现和访问不同于Microsoft 和框架的数据库的信息。网。它能够支持大多数数据库服务器以及 Microsoft Access、Oracle、MySQL、DB2、PostgreSQL、SQLite、InterBase、FireBird&#xff0c;最后是 Microsoft SQL Server。它可以通过 ODBC、OLE DB、ADO…

我来跟你讲vue进阶

一、组件&#xff08;重点&#xff09; 组件&#xff08;Component&#xff09;是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素&#xff0c;封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用&#xff0c;几乎任意类型的应用的界面都可以抽象…

ThreadLocal 的简单使用并深扒其实现原理

在多线程环境下, 如果想要保证每个线程都能独立于其它线程独自运行, 可以使用 ThreadLocal 来解决; ThreadLocal 就是用于提供线程局部变量的一个工具, 也就是说 ThreadLocal 可以为每个线程创建一个单独的变量副本; 其概念与同步机制正好相反, 同步机制是保证多线程环境下数据…

elasticSearch写入原理

elasticSearch写入原理 最近学习完了es相关的课程整理除了es的核心内容&#xff0c;学习这东西知其然知其所以然&#xff0c;自己按照自己的理解整理了es相关的面试题。先热个身&#xff0c;整理一下es的写入原理&#xff0c;有不对的地方请大家指正。 这些原理的东西我觉得还是…

MySql数据库(进阶篇)

&#x1f44c; 棒棒有言&#xff1a;人生总是在前行&#xff0c;不论走到哪里&#xff0c;只要带着信念往前走&#xff0c;比别人多一点努力&#xff0c;你就会多一份成绩&#xff1b;比别人多一点志气&#xff0c;你就会多一份出息&#xff1b;比别人多一点坚持&#xff0c;你…

js学习3(数组)

目录 结构图 数组操作 每日一练 结构图 数组操作 ## 数组中可以存储任何类型元素 ## 创建&#xff1a; 字面量([...])、创建对象(new Array(arr_len)) ## 遍历&#xff1a; 循环遍历、forEach(callback)、map(callback)、filter(callback)、every(callback)、some(callback)、…