JVM从1%到99%【精选】-类加载子系统

目录

1.类的生命周期

1.加载 

2.连接 

3.初始化 

2.类的加载器 

1.类加载器的分类 

2.双亲委派机制 

3.面试题:类的双亲委派机制是什么? 

4.打破双亲委派机制

1.类的生命周期

类加载过程:加载、链接(验证、准备、解析)、初始化。这个过程是在类加载子系统完成的。 

1.加载 

  • 根据类的全限定名把字节码文件的内容加载并转换成合适的数据放入内存中,存放在方法区和堆上。
  • 1.通过一个类的全限定名获取定义此类的二进制字节流
  • 2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  • 3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

2.连接 

  • 将类的二进制数据合并到JRE中。
  • 验证
    • 目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。

    • 主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证

      • 文件格式验证:验证字节码文件是否符合规范。

        • 魔数:是否魔数0xCAFEBABE开头

        • 版本号:版本号是否在JVM兼容范围

        • 常量类型:类常量池里常量类型是否合法

        • 索引值:索引值是否指向不存在或不符合类型的常量。

      • 元数据验证:元数据是字节码里类的全名、方法信息、字段信息、继承关系等。

        • 标识符:验证类名接口名标识符有没有符合规范

        • 接口实现方法:有没有实现接口的所有方法

        • 抽象类实现方法:有没有实现抽象类的所有抽象方法

        • final类:是不是继承了final类。

      • 指令验证:主要校验类的方法体,通过数据流和控制流分析,保证方法在运行时不会危害虚拟机安全。

        • 类型转换:保证方法体中的类型转换是否有效。例如把某个类强转成没继承关系的类

        • 跳转指令:保证跳转指令不会跳转到方法体以外的字节码指令上;

        • 保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作。

      • 符号引用验证:确保后面解析阶段能正常执行。

        • 类全限定名地址:验证类全限定名是否能找到对应的类字节码文件

        • 引用地址:引用指向地址是否存在实例
        • 引用权限:是否有权引用
  • 准备
    • 为类变量分配内存并且设置该类变量的默认初始值,即零值。
    • 这里不包含用final修饰的static,因为fina1在编译的时候就会分配了,准备阶段会显式初始化;
    • 这里不会为实例变量分配初始化,类变量会在方法区中,而实例变量是会随着对象一起分配到Java堆中。
  • 解析
    • 将常量池内的符号引用转换为直接引用部过程。
    • 事实上,解析操作往往会伴随着JVM在执行完初始化之后再执行。

3.初始化 

  • 初始化阶段会执行静态代码块中的代码,并为静态变量赋值。
  • 1.静态变量的定义使用final关键字,这类变量会在准备阶段直接进行初始化(除非要执行方法)。
  • 2.直接访问父类的静态变量,不会触发子类的初始化。子类的初始化cinit调用之前,会先调用父类的cinit初始化方法。

2.类的加载器 

  • 类加载器:是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。
  • 作用:类加载器(ClassLoader)负责在类加载过程中的字节码获取并加载到内存这一部分。通过加载字节码数据放入内存转换成byte]],接下来调用虚拟机底层方法将byte]]转换成方法区和堆中的数据。

1.类加载器的分类 

类加载器分为两类,一类是Java代码中实现的,一类是Java虚拟机底层源码实现的。

  • 1.启动类加载器:默认加载Java安装目录/jre/lib下的类文件或通过 -Xbootclasspath 参数指定路径中的,且被虚拟机认可(按文件名识别,如 rt.jar)的类。
  • 2.扩展类加载器:默认加载Java安装目录/jre/lib/ext下的类文件或通过 java.ext.dirs 系统变量指定路径中的类库。
  • 3.应用程序类加载器:负责加载用户路径(classpath)上的类库。

2.双亲委派机制 

  • 由于Java虚拟机中有多个类加载器,双亲委派机制的核心是解决一个类到底由谁加载的问题。

  • 双亲委派机制
    • 自底向上查找是否加载过,再由顶向下进行加载。
      • 向上查找如果已经加载过,就直接返回Class对象,加载过程结束。这样就能避免一个类重复加载。
      • 如果所有的父类加载器都无法加载该类,则由当前类加载器自己尝试加载。所以看上去是自顶向下尝试加载。

3.面试题:类的双亲委派机制是什么? 

  • 1、当一个类加载器去加载某个类的时候,会自底向上查找是否加载过,如果加载过就直接返回,如果一直到最顶层的类加载器都没有加载,再由顶向下进行加载。
  • 2、应用程序类加载器的父类加载器是扩展类加载器,扩展类加载器的父类加载器是启动类加载器。
  • 3、双亲委派机制的好处有两点:第一是避免恶意代码替换JDK中的核心类库,比如java.lang.String,确保核心类库的完整性和安全性。第二是避免一个类重复地被加载。

4.打破双亲委派机制

打破双亲委派机制的三种方式:

  • 1.自定义类加载器自定义类加载器并且重写loadClass方法,就可以将双亲委派机制的代码去除。
  • 2.线程上下文类加载器利用上下文类加载器加载类,比如JDBC和JNDI等。
  • 3.Osgi框架的类加载器:历史上osgi框架实现了一套新的类加载器机制,允许同级之间委托进行类的加载 。

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

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

相关文章

第五十二周:文献阅读+STHTNN

目录 摘要 Abstract 文献阅读:用于区域空气质量预测的时空分层传输神经网络 现有问题 提出方法 创新点 方法论 周期特征提取组件(PFEC) 场景动态图模块(SDGM) 时空特征提取组件(STEC) 传输注意力模块(TransATT) STHTNN模型 研究实验 数据集…

03、SpringBoot 源码分析 - SpringApplication启动流程三

SpringBoot 源码分析 - SpringApplication启动流程三 初始化基本流程SpringApplication的setListeners设置监听器deduceMainApplicationClass对端主启动类rungetRunListeners获取SpringApplicationRunListener监听器EventPublishingRunListener的构造方法SimpleApplicationEven…

解决 Content type ‘application/json;charset=UTF-8‘ not supported

文章目录 问题描述原因分析解决方案参考资料 问题描述 我项目前端采用vue-elementUi-admin框架进行开发,后端使用SpringBoot,但在前后端登录接口交互时,前端报了如下错误 完整报错信息如下 前端登录接口JS代码如下 export function login(…

JVM堆内存分析

jmap工具查看堆内存 jmap:全称JVM Memory Map 是一个可以输出所有内存中对象的工具,可以将JVM中的heap(堆),以二进制输出成文本,打印出Java进程对应的内存 找到pid jmap -heap 19792 Attaching to process ID 19792…

Word应用:一键提取手写签名

1、将带有签名的图片插入到word文档中,裁剪出签名部分; 2、点击“格式-颜色”,选择“重新着色”中的“黑白50%”; 3、“格式-颜色”,设置透明色; 4、选择“文件”选项卡,选择打开“选项”,点击“…

【动态规划】子序列问题I|最长递增子序列|摆动序列|最长递增子序列的个数|最长数对链

一、最长递增子序列 300. 最长递增子序列 算法原理: 💡细节: 1.注意子序列和子数组的区别: (1)子序列:要求顺序是固定的(要求没那么高,所以子序列就多一些) (2)子数组:要…

MyCat实现分库分表

两个集群 两个库 两个表 搭建数据库服务使用docker启动两个mysql 3506 3507连接MyCat创建两个数据源连接MyCat创建集群 mycat创建逻辑库MyCat创建全局表广播表创建分片表mycat逻辑库MyCat插入数据mycat查看数据物理库3506查看数据物理库3507查看数据 ER表创建ER表mycat插入数据…

Codigger:Vim的革新者,提升开发体验和功能性

深知Vim在编程和文本编辑领域的卓越地位,因此,在设计和开发过程中,Codigger始终将保留Vim的核心功能和高度定制能力作为首要任务。然而,Vim的复杂性和高度定制性也让很多新用户望而却步。为了降低这种使用门槛,Codigge…

什么是XXE漏洞,日常如何做好web安全,避免漏洞威胁

随着网络技术的不断发展,网站安全问题日益受到人们的关注。当前随着技术发展,网站存在一些常见的可能被攻击者利用的漏洞,而在众多网站安全漏洞中,XXE(XML External Entity)漏洞是一个不容忽视的问题。今天…

Git的安装和配置

一、Git的介绍 代码的一套托管工具,它分为两个仓库,首先将你写的代码提交到本地仓库,这个时候只有你可以看,和你一起开发的同事看不到。将本地仓库的代码推到远程仓库(githab、gitee、gitlab等之一)&#…

使用Flask-Admin创建强大的后台管理系统

文章目录 安装Flask-Admin创建Flask应用添加Flask-Admin添加模型扩展延伸自定义视图权限管理文件上传 结语 在Web应用开发中,后台管理系统是至关重要的组成部分,它能够让管理员轻松管理应用的各种数据和配置。Flask-Admin是一个功能强大的Flask扩展&…

vue的css深度选择器 deep /deep/

作用及概念 当 <style> 标签有 scoped 属性时&#xff0c;它的 CSS 只作用于当前组件中的元素&#xff0c;父组件的样式将不会渗透到子组件。在vue中是这样描述的&#xff1a; 处于 scoped 样式中的选择器如果想要做更“深度”的选择&#xff0c;也即&#xff1a;影响到子…