【JVM】---- 类加载机制

目录

1. 类加载过程

2. 类加载器

一、类加载过程

1. 类加载过程:

分为三步:加载->连接->初始化

其中连接过程分为: 验证->准备->解析

图示
            

1.1 什么时候开始的初始化?

(1)最常见的Java代码场景:
    1.使用new关键字实例化对象的时候
    2.读取或设置一个类的静态字段的时候(被final修饰、已在编译器把结果放入常量池的静态字段除外)
    3.调用一个类的静态方法的时候。
(2)使用java.lang.reflect包的方法对类进行反射调用的时候,
(3)初始化一个类的时候,如果其父类没有进行过初始化,则先对其父类初始化
(4)虚拟机启动时候,指定一个要执行的主类(包含main()方法的那个类)
(5)如果一个Java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic,REF_outStatic,REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。

1.2 "加载"阶段

  "加载"是"类加载"过程的一个阶段,注意不要混淆,在加载阶段,需要完成以下3件事情
    (1)通过一个类的全限定名来获取定义此类的二进制字节流
    (2)将这个字节流所代表的静态存储结构转换为方法区的运行时数据结构
    (3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

  加载阶段完成后,二进制字节流就按照虚拟机所需的格式存储在方法区之中

1.3 准备

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

  注意:这时候进行内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量会在对象实例化随着对象一起分配在Java堆中。这里的初始值"通常情况"下是数据类型的零值。如果类字段的字段属性表中存在ConstantValue属性,那么在准备阶段变量value就会被初始化为ConstantValue属性所指定的值

	// value在准备阶段过后的初始值为0而不是123
    public static int value = 123;
    
    // 编译时Javac将会为value生成ConstantValue属性
    // 在准备阶段虚拟机会根据ConstantValue的设置将value赋值为123
    public static final int value1 = 123;

二、类加载器

1.定义

    类加载阶段中的"通过一个类的全限定名来获取描述此类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类,实现这个动作的代码模块称为""类加载器“

每个 Class 对象的内部都有一个 classLoader 字段来标识自己是由哪个ClassLoader加载。ClassLoader就像一个容器,里面装了很多已经加载的 Class 对象。
在这里插入图片描述

2.双亲委派模型
2.1 三种系统提供的类加载器
  • 启动类加载器(Bootstrap ClassLoader),负责加载<JAVA_HOME>\lib目录,如rt.jar
  • 扩展类加载器(Extension ClassLoader),负责加载<JAVA_HOME>\lib\ext目录
  • 应用程序类加载器(Application ClassLoader),负责加载用户类路径(ClassPath)上所指定类库
2.2 双亲委派工作过程

    如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类。而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。(类加载器之间的父子关系一般不会以继承的关系来实现,而是都使用组合关系来复用父加载器的代码)

2.3 工作过程详情

Application ClassLoader 在加载一个未知的类名时,它并不是立即去搜寻 Classpath,它会首先将这个类名称交给 Extension ClassLoader来加载,如果ExtensionClassLoader可以加载,那么 Application ClassLoader 就不用加载了。否则它就会搜索 Classpath 。
而Extension ClassLoader 在加载一个未知的类名时,它也并不是立即搜寻 ext 路径,它会首先将类名称交给 Bootstrap ClassLoader来加载,如果 Bootstrap ClassLoader 可以加载,那么 Extension ClassLoader 也就不用加载了。否则它就会搜索 ext 路径下的 jar 包。
这三个 ClassLoader 之间形成了级联的父子关系,每个 ClassLoader 都很懒,尽量把工作交给父亲做,父亲干不了了自己才会干。每个 ClassLoader 对象内部都会有一个 parent 属性指向它的父加载器。
在这里插入图片描述

2.4 双亲委派模型的好处

双亲委派模型保证了Java程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了Java的核心API不被篡改。如果没有使用双亲委派模型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object 类(存放在rt.jar中)的话,那么程序运行的时候,系统就会出现多个不同的 Object 类。

2.5 如何避免双亲委派机制

自己定义一个类加载器,重写 loadClass() 。

Mark

  • 这块的知识点有点难啃,以后会回来改正的和补充的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值