首页 > 编程语言 >深入理解Java虚拟机 --- 类加载机制

深入理解Java虚拟机 --- 类加载机制

时间:2024-11-08 13:19:08浏览次数:5  
标签:初始化 Java 虚拟机 --- 父类 ClassLoader 加载

类的生命周期

类的生命周期:加载→验证→准备→解析→初始化→使用→卸载

类加载的时机

关于在什么情况下需要需要开始类加载过程的第一个阶段"加载",虚拟机并没有进行强制约束,这点交给虚拟机的具体实现来自由把握。

但严格规定了有且只有六种情况必须立即对类进行"初始化":

(字节码指令:new、getstatic、putstatic、invokestatic)

1、遇到new关键字实例化对象的时候。

2、读取或设置一个类型的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)的时候。

3、调用一个类型的静态方法的时候。

4、使用java.lang.reflect包的方法对类型进行反射调用的时候。

5、当初始化类的时候时,发现其父类还没有进行初始化,需要先触发父类的初始化。

6、当虚拟机启动时,用户需要指定一个要执行的主类(包括main()),那么就会触发该类的初始化。

类的主动使用和被动使用

主动使用:对类主动进行初始化。在上述六种情况。

被动使用:被动使用不会初始化类,但可能会导致类的加载。

1、通过子类引用访问父类的静态字段,不会造成子类的初始化。

2、使用数组定义引用类,不会触发引用类的初始化。

Tips:创建数组的字节码指令为**newarray**。

3、访问类的静态常量

常量在编译的时候会存入调用类的常量池中,本质上没有直接引用到定义常量的类

类加载的过程

加载

目的:

1、通过一个类的全限定名来获取描述该类的二进制字节流。

2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

3、在内存中生成一个代表该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

类加载器

设计团队想把类加载阶段中"通过一个类的全限定名来获取描述该类的二进制字节流"放到Java虚拟机外部去做,以便让应用程序自己决定如何去获取所需类

实现这个动作的代码被称为类加载器

作用:加载类。

image.png

引导类加载器

Bootstrap ClassLoader:是用C语言写的,不是ClassLoader的子类。被称为根装载器。它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类。

Bootstrap ClassLoader只加载包名为java、javax、sun等开头的类。

扩展类加载器

Extension ClassLoader:Bootstrap Loader加载ExtClassLoader,并将ExtClassLoader的父加载器设置为Bootstrap Loader。其是用Java写的。ExtClassLoader主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中类库。

继承于ClassLoader类。

系统类加载器

Application ClassLoader:Bootstrap Loader加载ExtClassLoader后,就会加载AppClassLoader,并将AppClassLoader的父加载器指定为ExtClassLoader。AppClassLoader主要负责加载classpath所指定的位置的类或者是jar文档,它也是Java程序默认的类加载器。

双亲委派机制

双亲委派机制:指先委托父类装载器去寻找目标类,如果父类装载器寻找不到,再从自己负责的路径下寻找目标类。

双亲委派机制主要在ClassLoader中的loadClass方法中体现。

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        //用synchronized保证加载时类只加载一个Class类
        synchronized (getClassLoadingLock(name)) {
            // 首先,检查请求的类是否已经被加载过了
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    //双亲委派机制
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // 如果父类加载器抛出ClassNotFoundException
                    // 说明父类加载器无法完成加载请求
                }

                if (c == null) {
                    // 在父类加载器无法加载时
                    // 再调用本身的findClass方法来进行类加载
                    c = findClass(name);
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

双亲委派模型的优点:

  • Java类伴随着它的类加载器一起具备了一种带有优先级的层级关系,通过这种层级关系可以避免类的重复加载。

  • 保护程序安全,防止核心API被篡改。

双亲委派模型的缺点:

  • 顶层的ClassLoader无法访问底层ClassLoader加载的类。

双亲委派模型的破坏:

第一次:还没有出现双亲委派模型之前。

第二次:为了解决顶层ClassLoder无法访问底层ClassLoader加载的类,引入了线程上下文类加载器

线程上下文加载器:通过Thread类的setContextClassLoader()方法设置,如果创建线程时未设置,那么会从父线程中继承,**如果在应用程序的全局范围都没有设置过,默认为应用类加载器**。

第三次:由于用户对于程序动态性的追求导致的。如:代码热替换、模块热部署等。

验证

目的:确保Class文件字节流中包含的信息符合规范,保证不会危害虚拟机的安全。

文件格式校验:

魔数、版本号、常量池

元数据校验:

类是否有父类(除了Object,所以类都有父类)、类是否实现了接口的所有方法

字节码验证:

目的:通过数据流分析和控制流数据分析,确定程序语义是合法的、符合逻辑的。

符号引用验证:

目的:确保解析行为能正常运行

准备

为类中定义的静态变量分配内存并设置类变量初始值的阶段。

解析

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

符号引用:用字面量来描述所引用的目标。

直接引用:可以直接指向目标的指针。

初始化

初始化阶段就是执行类构造器()方法的过程。

标签:初始化,Java,虚拟机,---,父类,ClassLoader,加载
From: https://www.cnblogs.com/ayu0v0/p/18534875

相关文章

  • 开源模型应用落地-glm模型小试-glm-4-9b-chat-tools使用(五)
    一、前言  GLM-4是智谱AI团队于2024年1月16日发布的基座大模型,旨在自动理解和规划用户的复杂指令,并能调用网页浏览器。其功能包括数据分析、图表创建、PPT生成等,支持128K的上下文窗口,使其在长文本处理和精度召回方面表现优异,且在中文对齐能力上超过GPT-4。与之前的GLM系列......
  • JavaLin第六章:JavaLin的访问管理和默认响应
    文章目录前言一、JavaLin的访问管理二、JavaLin的默认响应总结前言最近忙起来了,就没有更新了,实在不不好意思,最近会进行javalin的陆陆续续的更新,希望大家支持。在Java里面有很多框架,其中权限管理是一个非常重要的功能实现,对于每个用户设定该用户的角色,对应相应用户......
  • 复制下来就能跑:Java智能问答系统-介绍与代码实践 - 基于springboot_springai_国产大模
    本文的目的是在5分钟内能把智能问答系统的原理和实践讲明白代码可执行,复制粘贴即可,可以快速跑起来。智能问答系统简介智能问答系统是一种人工智能应用,它能够理解用户提出的问题,并通过自然语言处理技术来分析和理解问题的含义。随后,系统会在其知识库中搜索相关信息,以生成......
  • 庖丁解java(一篇文章学java)
    (大家不用收藏这篇文章,因为这篇文章会经常更新,也就是删除后重发) 一篇文章学java,这是我滴一个执念...当然,真一篇文章就写完java基础,java架构,java业务实现,java业务扩展,根本不可能.所以,这篇文章,就是一个索引,索什么呢?  请看下文...关于决定开始写博文的介绍......
  • 【补档】玄武550电源怎么样? - 约呼的回答 - 知乎
    【补档】玄武550电源怎么样?-约呼的回答-知乎约呼一个路过的图吧用户低预算整机非常推荐,高预算慎选。低预算整机非常推荐,高预算慎选。优点不少,缺点也有。先说优点:价格上来说便宜大碗,用料不错,部分型号反向虚标,比如550v4其实是按650w规格用料来做的,拆解视频一堆,相对透明,售......
  • MM--项目中遇到的一些问题记录
    采购订单:创建采购订单时,供应商对应的信息记录已失效,但是切换供应商之后价格不会自动更新成01.SU01-查看用户对应的采购缺省值  2.SPRO-维护采购缺省值 采购订单收货的时候,提示无符合条件的行项目经打断点发现是由于程序中判断时公司间的内部交易所导致的,根本原......
  • c语言入门学习这一篇就够了-知识点总结(三万字二级必看)
    C语言   C语言是中高级语言的代表之一,它是所有现代编程语言的基石,包括C++、Java、C#、Python、JavaScript、Swift等。C语言是学习其他编程语言的基础,因为它提供了对系统底层的精确控制,这使得它在开发操作系统、驱动程序、嵌入式系统、高性能计算等领域中有着不可替代的......
  • Me-LLaMA——用于医疗领域的新型开源大规模语言模型
    摘要大规模语言模型的出现是提高病人护理质量和临床操作效率的一个重大突破。大规模语言模型拥有数百亿个参数,通过海量文本数据训练而成,能够生成类似人类的反应并执行复杂的任务。这在改进临床文档、提高诊断准确性和管理病人护理方面显示出巨大的潜力。然而,像ChatGPT和......
  • 理解Web登录机制:会话管理与跟踪技术解析(四)-拦截器Interceptor、异常处理
    本文将详细探讨如何通过拦截器实现登录校验,并介绍如何通过异常处理来确保系统的鲁棒性。我们将通过具体的示例,深入分析如何在Spring框架中配置拦截器与异常处理,以便为开发者提供一套高效、安全的登录校验和异常管理方案。目录前言拦截器Interceptor快速入门Interceptor......
  • 华为OD机试真题-整数编码-2024年OD统一考试(E卷)
    最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客     每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。题目描述实现一种整数编码方法......