JVM (二)类加载

news2024/11/15 3:48:20

一,类的生命周期


  1. 加载

  2. 连接

    1. 验证

    2. 准备

    3. 解析

  3. 初始化

  4. 使用

  5. 卸载

  • 加载、验证、准备和初始化这四个阶段发生的顺序是确定的,而解析阶段则不一定;

  • 类加载几个阶段按顺序开始,而不是按顺序进行或完成,通常都会交叉进行;

1,加载

  1. 通过一个类的全限定名来获取二进制字节流(加载.class文件的方式:本地、网络、数据库等);
  2. 将字节流所代表的静态存储结构转化为 方法 的运行时数据结构;
  3. Java堆 生成一个代表这个类的 Class对象( 类加载的 最终产品),Class对象封装了类在方法区内的数据结构,并且提供了访问方法区内的数据结构的接口。
  • 类加载器:可用系统的或自定义的;
  • JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,预加载时遇到错误,类加载器须在程序首次主动使用该类时才报告错误(没使用就不会报错)

2,连接

    1,验证:确保被加载类的正确性
  • 是否以0xCAFEBABE开头、 主次版本号是否在当前虚拟机的处理范围、 是否有父类、语义是否合法等;
    2,准备:为类的静态变量分配内存,并将其初始化为默认值
  • 仅分配静态变量,实例变量会在实例化时随着对象一块分配在Java堆;
  • 所设置的初始值通常情况下是数据类型默认的零值(如0、0L、null、false等),而不是显式地赋予的值;
  • 如果字段同时被final和static修饰,那么会被初始化为指定的值
    3,解析:把类中的符号引用转换为直接引用,解析动作并不一定在初始化动作完成之前,也有可能在初始化之后。JVM - 符号引用转化为直接引用_符号引用转为直接引用-CSDN博客

3,初始化

主要对类变量进行初始化,有两种方式:
① 声明类变量时指定初始值;
② 使用静态代码块为类变量指定初始值;
  1. 步骤:
    1. 假如这个类还没有被加载和连接,则程序先加载并连接该类;
    2. 初始化父类、执行初始化语句、构造函数等,参考: JVM 类初始化过程
  2. 时机: 只有 当对类的主动使用 的时候才会导致类的初始化,主动使用包括六种:
    1.new对象;
    2.访问某个类或接口的静态变量,或者对该静态变量赋值;
    3.调用类的静态方法;
    4.反射(如 Class.forName(“com.shengsiyuan.Test”));
    5.初始化某个类的子类,则其父类也会被初始化;
    6.Java虚拟机启动时被标明为启动类的类(JavaTest),直接使用java.exe命令来运行某个主类;

二,类加载器


类加载器的层次关系:
  • 父类加载器并不是通过继承关系来实现的,而是采用组合实现的。

1,三个类加载器

启动类加载器:BootstrapClassLoader
  • 加载存放在 JDK\jre\lib下,或被 -Xbootclasspath参数指定的路径中的,并且能被虚拟机识别的类库(如rt.jar,所有的java.开头的类均被 BootstrapClassLoader加载);
  • 启动类加载器是无法被Java程序直接引用的。
扩展类加载器: ExtClassLoader
  • 加载 JDK\jre\lib\ext中,或者由 java.ext.dirs系统变量指定的路径中的所有类库(如javax.开头的类),开发者可以直接使用扩展类加载器;
应用程序类加载器: AppClassLoader
  • 负责加载用户类路径(ClassPath)所指定的类,一般情况下这个就是程序中默认的类加载器;

2,JVM类加载机制

全盘负责
当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入。
父类委托:双亲委派模型
先让父类加载器试图加载该类,所有的类加载请求最终都应该被传递到顶层的启动类加载器中只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。
步骤:
  • 1、当  AppClassLoader 加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器 ExtClassLoader 去完成。
  • 2、当  ExtClassLoader 加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader去完成。
  • 3、如果  BootStrapClassLoader 加载失败(例如在  $JAVA_HOME / jre / lib 里未查找到该class),会使用  ExtClassLoader 来尝试加载;
  • 4、若ExtClassLoader也加载失败,则会使用  AppClassLoader 来加载,如果  AppClassLoader 也加载失败,则会报出异常  ClassNotFoundException
意义
  • 系统类防止内存中出现多份同样的字节码
  • 保证Java程序安全稳定运行
缓存机制
所有加载过的Class都会被缓存。当程序使用某个Class时,类加载器先从缓存区寻找该Class,缓存不存在时才加载类并存入缓存区。这就是为什么修改了Class后,必须重启JVM,程序的修改才会生效。

三,类的加载方式


类加载有三种方式:
  • 1、命令行启动应用时候由JVM初始化加载
  • 2、通过Class.forName()方法动态加载
  • 3、通过ClassLoader.loadClass()方法动态加载

四,自定义类加载器


有时候我们需要自定义类加载器。比如应用是通过网络来传输 Java类的字节码,为保证安全性,这些字节码经过了加密处理,这时系统类加载器就无法对其进行加载,这样则需要自定义类加载器来实现。

自定义类加载器一般都是继承自 ClassLoader类,从上面对 loadClass方法来分析来看,我们只需要重写 findClass 方法即可。

自定义类加载器的核心在于对字节码文件的获取,如果是加密的字节码则需要在该类中对文件进行解密。由于这里只是演示,并未对class文件进行加密,因此没有解密的过程。这里有几点需要注意:

  • 这里传递的文件名需要是类的全限定性名称;
  • 最好不要重写loadClass方法,因为这样容易破坏双亲委托模式;
  • 这类Test 类本身可以被  AppClassLoader 类加载,因此不能把 com / paddx / test / classloading / Test . class 放在类路径下。否则会直接导致该类由  AppClassLoader 加载;
 
 
 

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

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

相关文章

2024 New Relic Java 生态系统报告

New Relic 发布了 2024 年度 Java 生态系统报告,数据来源于使用 New Relic 监控的线上 Java 应用。从这个报告中,我们可以看到 Java 发展的一些趋势。 在 Java 版本方面,新版本的使用率越来越高。Java 11 的使用率是 32.9%,Java 1…

Github 2024-06-12 C开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-12统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10PHP项目1PLpgSQL项目1C++项目1Ventoy: 100%开源的可启动USB解决方案 创建周期:1534 天开发语言:C协议类型:GNU General Public Licen…

软件架构风格探析

软件架构是系统设计的基石,它定义了不同组件、层次之间的交互和整合方式。选择恰当的架构风格对于构建高效、可维护以及可扩展的软件系统至关重要。本文将详细探讨几种关键的软件架构风格,包括数据流风格、仓库、调用返回、独立构件和虚拟机,…

课时152:项目发布_手工发布_方案解读

1.2.1 方案解读 学习目标 这一节,我们从 基础知识、简单实践、小结 三个方面来学习 基础知识 案例需求 实现一套业务环境的项目发布流程,基本的网站架构效果如下:架构解读:负载均衡采用Nginx服务,基于请求内容进行…

18.3 HTTP服务器-响应不同类型的内容和请求、获取请求数据

1. 响应不同类型的内容 在向客户端返回响应时,服务器应根据客户端的具体需求,为其提供不同类型的内容。一些常见的内容类型包括: text/plain —— 纯文本格式 text/html —— HTML格式 application/json —— JSON格式 application/xml —…

Java多线程CompletableFuture使用

引言 一个接口可能需要调用N个其他服务的接口,这在项目开发中非常常见。如果是串行执行的话,接口的响应速度会很慢。考虑到这些接口之间有大部分都是无前后顺序关联的,可以并行执行。就比如说调用获取商品详情的时候,可以同时调用…

高效换热管

绕管式高效换热器 绕管换热器是一种结构紧凑,传热效率高的新型高效换热器。换热管按螺旋线形状交替缠绕在芯筒与外筒之间,相邻两层螺旋状换热管旋向相反,并采用一定形状的定距元件使之保持一定间距。层与层间换热管反向缠绕,极大…

解决python import时ModuleNotFoundError异常

文章目录 前言 一 import索引机制二 ModuleNotFoundError原因及其解决办法1. 模块,包名字错误2. 模块,包未导入或未安装3. 模块,包命名冲突4. 模块,包路径不在import索引范围内(常见且重点) 前言 在学习和使用python import xxx时…

“改进型”Howland 电流泵电路

“改进型”Howland 电流泵电路 “改进型”Howland 电流泵是一种使用差分放大器在分流电阻器 (Rs) 上施加电压的电路,从而产生能够驱动大范 围负载电阻的双极性(拉电流或灌电流)压控电流源。 设计注释 确保运算放大器的输入端(V…

Spring应用如何打印access日志和out日志(用于分析请求总共在服务耗费多长时间)

我们经常会被问到这样一个问题。你接口返回的好慢呀,能不能提升一下接口响应时间啊?这个时候我们就需要去分析,为什么慢,慢在哪。而这首先应该做的就是确定接口返回时间过长确实是在服务内消耗的时间。而不是我们将请求发给网关或…

STM32高级篇—按键FIFO

想成问一名非常优秀的嵌入式软件工程师,是需要掌握很多知识的。 完成STM32的基础内容的学习后,我们也进入到学习STM32高级的内容上。 本人也是一名嵌入式的初级入坑人,写的内容可能会有错误,或者不正确的地方也请大家多多指教&…

1.0 Android中Activity的基础知识

一:Activity的定义 Activity是一个应用组件,它提供了一个用户界面,允许用户执行一个单一的、明确的操作,用户看的见的操作都是在activity中执行的。Activity的实现需要在manifest中进行定义,不让会造成程序报错。 1.…

【动态规划】| 路径问题之不同路径 力扣62

🎗️ 主页:小夜时雨 🎗️ 专栏:动态规划 🎗️ 如何活着,是我找寻的方向 目录 1. 题目解析2. 代码 1. 题目解析 题目链接: https://leetcode.cn/problems/unique-paths/description/ 通常动态规划的题目有…

【Linux】解决由于 network和 NetworkManager不兼容,导致的网络服务错误

今天尝试启动在虚拟机中启动一些中间件环境(用docker管理),使用ssh连接虚拟机,却始终无法连接 我怀疑是不是虚拟机的ip地址改变了,但是之前我的虚拟机ip已经在 /etc/sysconfig/network-scripts 目录下,创…

PCA与LDA

共同点 降维方法: PCA和LDA都是数据降维的方式,它们都能通过某种变换将原始高维数据投影到低维空间。 数学原理: 两者在降维过程中都使用了矩阵特征分解的思想,通过对数据的协方差矩阵或类间、类内散度矩阵进行特征分解&#xff…

Vue项目实践:使用滚动下拉分页优化大数据展示页面【通过防抖加标志位进行方案优化】

Vue项目实践:使用滚动下拉分页优化大数据展示页面 前言 传统的分页机制通过点击页码来加载更多内容,虽然直观,但在处理大量数据时可能会导致用户体验不佳。相比之下,滚动下拉分页能够在用户滚动到页面底部时自动加载更多内容&…

实现JWT认证与授权的Spring Boot项目详解

我们将详细介绍如何使用JWT(JSON Web Tokens)结合Spring Boot框架实现用户认证和授权系统。此方案将包括用户注册、登录以及通过JWT令牌进行后续请求的身份验证过程。我们将从引入必要的依赖开始,然后逐步构建项目的各个部分,包括…

如何查看当前的gruop_id 的kafka 消费情况 这个可以查看到是否存在消费阻塞问题

如何查看当前的gruop_id 的kafka 消费情况 这个可以查看到是否存在消费阻塞问题 命令如下: /kafka/bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group GWW --describe 其中 127.0.0.1 为zookeeper 服务器ip GWW 为对应要查看的group_id 如下…

从零到一建设数据中台(番外篇)- 数据中台UI欣赏

番外篇 - 数据中台 UI 欣赏 话不多说,直接上图。 数据目录的重要性: 数据目录是一种关键的信息管理工具,它为组织提供了一个全面的、集中化的数据资产视图。 它不仅记录了数据的存储位置,还详细描述了数据的结构、内容、来源、使…

800W-2300W-4500W-7000W线绕电阻器的选型参考

EAK线绕电阻器将普通电阻器材料的高脉冲稳定性与优化的导热和高度保护相结合。安装在导热表面上可进一步改善散热并提高稳定性。 EAK提供各种外壳设计和材料(如铝和钢)的导线电阻器。它们符合 UL508 的要求,在用作制动、充电、放电或加热电阻…