JVM上篇之类加载子系统

目录

类加载子系统

内存结构

类的生命周期

类的加载过程

加载

加载class文件方式

连接

验证

验证阶段

准备

解析

初始化

类加载器

介绍

作用

分类

引导类加载器

自定义类加载器

ClassLoader

获取ClassLoader途径

双亲委派机制

介绍

执行流程

好处

打破双亲委派


类加载子系统

内存结构

Class文件

类加载子系统

运行时数据区

        方法区

        堆

        程序计数器

        虚拟机栈

        本地方法栈

执行引擎

本地方法接口

本地方法库

类的生命周期

        类从被加载到虚拟机内存中开始到卸载出内存为止,整个生命周期为7个阶段:加载、验证、准备、解析、初始化、使用、卸载;其中前三个阶段统称为连接

 卸载:jvm结束生命周期

类的加载过程

class文件需要加载到虚拟机之后才能运行和使用;主要分为三步:加载、连接、初始化;其中连接又可以分为三步:验证、准备、解析

 /**
 *示例代码
 */
public class HelloLoader {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

加载

类加载过程的第一步;

主要为了完成3件事:

        1.通过全类名获取定义此类的二进制字节流

        2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构

        3.在内存中生成一个代表该类的class对象,作为方法区这些数据的访问入口

加载class文件方式

        从本地系统中直接加载

        通过网络获取

        从压缩包中获取

        运行时计算生成

        其他文件生成(jsp、html)

        从数据库中提取

        从加密文件中获取

连接

验证

主要是为了确保class文件字节流中包含的信息符合规范,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。

验证阶段

准备

为类变量分配内存且设置该类变量的默认初始值。

注意

        1.进行内存分配的仅包括类变量(静态变量),而不包括实例变量

        2.这里所设置的初始值"通常情况"下是数据类型默认的零值(如 0、0L、null、false 等),比如我们定义了public static int value=111 ,那么 value 变量在准备阶段的初始值就是 0 而不是 111(初始化阶段才会赋值)。特殊情况:比如给 value 变量加上了 final 关键字public static final int value=111 ,那么准备阶段 value 的值就被赋值为 111

解析

解析是虚拟机将常量池内的符号引用替换为直接引用的过程。

解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄、调用限制符等7种符号引用进行

初始化

        初始化阶段是执行初始化方法<clinit>()方法的过程,是类加载的最后一步,之后jvm才开始执行类中定义的程序代码。

        对于<clinit>()方法的调用,jvm会确保其在多线程环境的安全性,因为<clinit>()方法是带锁线程安全,所以在多线程环境下进行类初始化可能会引起线程堵塞,并且这种堵塞很难被发现

类加载器

介绍

类加载器是一个负责加载类的对象,用于实现类加载过程中加载这一步;每个Java类都有一个引用指向加载它的ClassLoader;数组类不是ClassLoader创建的,而是jvm直接生成

作用

系统加载class类型的文件主要分为3步:加载、连接、初始化;其中连接过程又可以分为3步:验证、准备、解析

类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识

分类

jvm支持两种类型的加载器。分别为:引导类加载器、自定义类加载器。

自定义加载器一般指程序开发中开发人员自定义的一类类加载器,但是jvm规范却没有这么定义,而是将所有派生于ClassLoader的类加载器都划分为自定义加载器。

引导类加载器

启动类加载器(引导类加载器,Bootstrap ClassLoader)

        这个类加载使用C/C++语言实现的,嵌套在JVM内部。

        它用来加载Java的核心库(JAVA_HOME/jre/lib/rt.jar、resources.jar或sun.boot.class.path路径下的内容),用于提供JVM自身需要的类

        并不继承自ava.lang.ClassLoader,没有父加载器。

        加载扩展类和应用程序类加载器,并指定为他们的父类加载器。

        出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类

扩展类加载器(Extension ClassLoader)

        Java语言编写,由sun.misc.Launcher$ExtClassLoader实现。

        派生于ClassLoader类

        父类加载器为启动类加载器

        从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/1ib/ext子目录(扩展目录)下加载类库。如果用户创建的JAR放在此目录下,也会自动由扩展类加载器加载。

应用程序类加载器(系统类加载器,AppClassLoader)

        java语言编写,由sun.misc.LaunchersAppClassLoader实现

        派生于ClassLoader类

        父类加载器为扩展类加载器

        它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库

        该类加载是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载

        通过ClassLoader#getSystemclassLoader() 方法可以获取到该类加载器

自定义类加载器

为什么要自定义类加载器?

        隔离加载类

        修改类加载的方式

        扩展加载源

        防止源码泄漏

实现步骤:

        1.需要继承 ClassLoader抽象类

        2.自定义的类加载逻辑写在findClass()方法中

        3.在编写自定义类加载器时,如果没有太过于复杂的需求,可以直接继承URLClassLoader类

ClassLoader

ClassLoader类是一个抽象类,其后所有的类加载器都继承自ClassLoader。

获取ClassLoader途径

1.获取当前ClassLoader

clazz.getClassLoader()

2.获取当前线程上下文的ClassLoader

Thread.currentThread().getContextClassLoader()

3.获取系统的ClassLoader

ClassLoader.getSystemClassLoader()

4.获取调用者的ClassLoader

DriverManager.getCallerClassLoader()

双亲委派机制

介绍

        当一个类收到了加载请求时,它是不会先自己去尝试加载的,而是委派给父类去完成,比如我现在要 new 一个 Person,这个 Person 是我们自定义的类,如果我们要加载它,就会先委派 App ClassLoader ,只有当父类加载器都反馈自己无法完成这个请求(也就是父类加载器都没有找到加载所需的 Class)时,子类加载器才会自行尝试加载。

        双亲委派模型并不是一种强制性的约束,只是 JDK 官方推荐的一种方式

执行流程

        1.在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载

        2.类加载器在进行类加载的时候,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成

        3.只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载(调用自己的 findClass() 方法来加载类)

protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException
{synchronized (getClassLoadingLock(name)) {//首先,检查该类是否已经加载过Class c = findLoadedClass(name);if (c == null) {//如果 c 为 null,则说明该类没有被加载过long t0 = System.nanoTime();try {if (parent != null) {//当父类的加载器不为空,则通过父类的loadClass来加载该类c = parent.loadClass(name, false);} else {//当父类的加载器为空,则调用启动类加载器来加载该类c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {//非空父类的类加载器无法找到相应的类,则抛出异常}if (c == null) {//当父类加载器无法加载时,则调用findClass方法来加载该类//用户可通过覆写该方法,来自定义类加载器long t1 = System.nanoTime();c = findClass(name);//用于统计类加载器相关的信息sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {//对类进行link操作resolveClass(c);}return c;}
}

好处

        避免类的重复加载

        保护程序安全,防止核心api被篡改

打破双亲委派

        自定义加载器的话,需要继承 ClassLoader 。如果我们不想打破双亲委派模型,就重写 ClassLoader 类中的 findClass() 方法即可,无法被父类加载器加载的类最终会通过这个方法被加载。但是,如果想打破双亲委派模型则需要重写 loadClass() 方法。

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

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

相关文章

软件UI自动化测试应该怎么做?对软件产品起到什么作用?

在软件开发过程中&#xff0c;开发人员需要编写大量的代码来实现软件产品的功能。而这些功能往往需要在用户界面上进行展示和操作&#xff0c;称为UI(User Interface)。UI自动化测试是为了检测软件界面是否符合预期的设计和用户操作&#xff0c;通过自动化测试工具和脚本&#…

Idea执行Pom.xml导入jar包提示sun.misc.BASE64Encoder jar找不到---SpringCloud工作笔记197

奇怪之前都是好好的,这个是因为,jdk的版本不对,重新打开以后自动被选择成jdk11了...记录一下 原因是从jdk9的时候,这个jar包已经被删除了,所以会报错,如果你用的是jdk自带的这个jar包就会报错,那么还可以,修改,不让他用jdk的,让他用 用org.apache.commons.codec.binary.Base64…

NSDT编辑器实现数字孪生

数字孪生的强大功能来自于将真实世界的资产与真实世界的数据联系起来&#xff0c;因此您可以更好地可视化它们。数字孪生使跨职能团队能够以交互式和沉浸式方式协作设计、构建、测试、部署和操作复杂系统。 如何创建数字孪生&#xff1f; 数字孪生是通过导入概念模型&#xf…

PBA.客户需求分析 需求管理

一、客户需求分析 1 需求的三个层次: Requirement/Wants/Pains 大部分人认为&#xff0c;产品满足不了客户需要&#xff0c;是因为客户告知的需求是错误的&#xff0c;这听起来有一些道理&#xff0c;却没有任何意义。不同角色对于需求的理解是不一样的。在客户的需求和厂家的…

四、RIP动态路由实验

拓扑图&#xff1a; 基本ip的配置已经配置好了&#xff0c;接下来对两台路由器配置rip协议&#xff0c;两台PC进行跨网段通讯 RIPv1版本只能识别ABC的大类网段&#xff0c;不能区分子网掩码&#xff0c;v2版本可以识别子网掩码 首先进入R1&#xff0c;进入rip&#xff0c;宣告…

栈实现深度优先搜索

引言 之前刚学DFS的时候并不完全理解为什么递归可以一直往下做&#xff0c;后来直到了递归的本质是栈&#xff0c;就想着能不能手写栈来代替递归呢。当时刚学&#xff0c;自己觉得水平不够就搁置了这个想法&#xff0c;今天上数据结构老师正好讲了栈的应用&#xff0c;其中就有…

华为云云耀云服务器L实例评测 | 实例评测使用之硬件参数评测:华为云云耀云服务器下的 Linux 网络监控神器 bmon

华为云云耀云服务器L实例评测 &#xff5c; 实例评测使用之硬件参数评测&#xff1a;华为云云耀云服务器下的 Linux 网络监控神器 bmon 介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什…

Python一步到位实现图像转PDF自动化处理详解

什么是 img2pdf 库&#xff1f; img2pdf 是一个 Python 库&#xff0c;它可以让你轻松地把多张图像转换为 PDF 文件。它支持多种图像格式&#xff0c;如 JPG, PNG, GIF, BMP 等&#xff0c;并且可以自动调整图像的大小和方向&#xff0c;以适应 PDF 的页面大小和方向。它还可以…

数据仓库DW-理论知识储备

数据仓库DW 数据仓库具备 采集数据、分析数据、存储数据的功能&#xff0c;最后得出一些有用的数据&#xff0c;一些目标数据来使用。 采集来自不同源的数据&#xff0c;然后对这些数据进行分析和计算得出一些有用的指标&#xff0c;提供数据决策支持。 数据的来源有&#xff…

供应链 | 零售商-供应商柔性承诺契约:一种鲁棒优化方法 (一)

论文解读&#xff1a;毕鑫宇 作者&#xff1a;Aharon Ben-Tal, Boaz Golany, Arkadi Nemirovski, Jean-Philippe Vial 引用&#xff1a;Ben-Tal, A., Golany, B. , Nemirovski, A., & Vial, J. P… (2005). Retailer-supplier flexible commitments contracts: a robust op…

SpringBoot篇之集成Jedis、Lettuce、Redisson

目录 前言一、详解Jedis、Lettuce 和 Redisson的区别二、SpringBoot集成2.1 集成Jedis2.2 集成Lettuce2.3 集成Redisson 总结 前言 大家好&#xff0c;我是AK&#xff0c;最近在做新项目&#xff0c;基于旧项目框架修改&#xff0c;正好最近也在整理springboot相关知识&#x…

游戏中的随机——“动态平衡概率”算法

前言 众所周知计算机模拟的随机是伪随机&#xff0c;但在结果看来依然和现实中的随机差别不大。 例如掷硬币&#xff0c;连续掷很多很多次之后&#xff0c;总有连续七八十来次同一个面朝上的情况出现&#xff0c;计算机中一般的随机函数也能很好模拟这一点。 但在游戏中&…

使用ChatGPT和MindShow一分钟生成PPT模板

对于最近学校组织的实习答辩&#xff0c;由于时间太短了&#xff0c;而且小编也特别的忙&#xff0c;于是就用ChatGPT结合MindShow一分钟快速生成PPT&#xff0c;确实很实用。只要你跟着小编后面&#xff0c;你也可以快速制作出这个PPT&#xff0c;下面小编就来详细介绍一下&am…

C语言中的文件操作函数

C语言中的文件操作函数_c语言文件操作函数_点子李的博客-CSDN博客C语言文件操作_c语言文件操作函数https://blog.csdn.net/qq_53332052/article/details/128470575?utm_mediumdistribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-1-128470575-blog-125…

Nginx - 反向代理与负载均衡

目录 一、Nginx 1.1、Nginx 下载 1.2、nginx 基础配置的认识 a&#xff09;第一部分&#xff1a;全局块 b&#xff09;第二部分&#xff1a;events 块 c&#xff09;第三部分&#xff1a;http 块 http 块中 内嵌的 server 块 1.3、一些常用配置 1.3.1、location 匹配级…

windows Vscode 连接 虚拟机,超详细,含免密免ip配置 以 linux 虚拟机为例

我们这里使用 ssh 进行连接&#xff0c;不了解 ssh 的也没关系&#xff0c;感兴趣的可以自己了解一下。 我的虚拟机是 Ubuntu20.04&#xff0c;如果出现与 Centos 不一样的操作可以自行替换。 &#xff08;应该不会有&#xff1f;&#xff1f;&#xff09; 一 . 登录虚拟机~&a…

2023年中国云计算软件市场规模、市场结构及市场份额情况分析[图]

云计算是分布式计算的一种&#xff0c;指的是通过网络“云”将巨大的数据计算处理程序分解成无数个小程序&#xff0c;然后&#xff0c;通过多部服务器组成的系统进行处理和分析这些小程序得到结果并返回给用户。云计算软件类型分为三类&#xff0c;即基础设施即服务、平台即服…

EMC Unity存储(VNXe) service Mode和Normal Mode的一些说明

本文介绍下EMC unity存储设备&#xff08;也包含VNXe存储设备&#xff09;的两种工作模式&#xff1a; Service mode&#xff1a;也叫做rescue mode&#xff0c;存储OS工作不正常或者有其他故障&#xff0c;就会进入这个模式&#xff0c;无法对外提供服务Normal mode&#xff…

深入JTS事务引擎:理论与实践相结合,掌握高效事务管理的秘诀

事务是可靠应用程序的构建块 如果您阅读过任何有关 J2EE 的介绍性文章或者书籍&#xff0c;那么就会发现&#xff0c;只有一小部分资料是专门针对 Java Transaction Service&#xff08;JTS&#xff09;或 Java Transaction API&#xff08;JTA&#xff09;的。这并不是因为 J…

基于SpringBoot的网上订餐系统

基于SpringBoot的网上订餐系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色&#xff1a;用户、管理员管理员&#xff1a;登录、个人中心、会员管理、…