JVM-类加载机制

名词解释
*.class文件的结构
查看指令: javap -verbose hello.class
包含信息:

结构信息(版本号,大小信息);

元数据(类,继承,接口,字段声明,方法声明);

方法信息(语句,表达式,异常,堆栈大小与类型,调试信息)

符号引用
符号引用符号引用就是 class 文件中的     
1. CONSTANT_Class_info 
2. CONSTANT_Field_info
3. CONSTANT_Method_info等类型的常量
符号引用以 一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可,使用符号引用时,被引用的目标不一定已经加载到内存中。
直接引用
直接引用可以是指向目标的指针,相对偏移量或是一个能间接 定位到目标的句柄
如果有 了直接引用,那引用的目标必定已经在内存中存在

参考:

个人理解,如果使用符号引用,虚拟机其实也不知道具体引用的类的内存地址,那么也就无法真正的调用到该类,所以要把符号引用转为直接引用,这样就能够真正定位到类在内存中的地址,如果符号引用转直接引用失败,就说明类还没有被加载到内存中,就会报错。

https://blog.csdn.net/weixin_38106322/article/details/109239971

类加载机制概述

1、类加载器把编译好的那些“.class”字节码文件给加载到JVM中,供后续代码运行来使用。
2、JVM基于自己的 字节码执行引擎,来执行加载到内存里的类。
3、类加载的时机
   一个类被使用到到时候
eg:比如你的代码中有一个“main()”方法,那么JVM就会从这个“main()”方法开始执行里面的代码。他需要哪个类的时候,就会使用类加载器来加载对应的类,反正对应的类就在“.class”文件中。
4、通过Java命令执行代码的大体流程如下:
java  xxx 指令 在Windows下对应就是一个exe文件。dll 相当于java jar包。
C++启动程序 -》创建java虚拟机 -》java类加载器 -》加载class文件

类加载机制详解

类是如何加载到jvm中
JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。

加载过程分析

1. 加载

通过类全名来获取定义此类的二进制字节流,
将字节流所代表的 静态存储结构转换为方法区中运行时数据结构
在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
扩展:
  • 静态存储结构:数据存储于class文件的结构。
  • 运行时数据结构:数据存储于JVM的数据结构。
  • 二进制流是从.class文件中获取的。这个class文件并不一定只来源于本地,也可以来源于网络等。

2. 连接

将java二进制代码合并到java运行状态中的过程。
  • 验证:校验字节码文件的正确性 目的保证class流的格式正确。
(简单来说,这一步就是根据Java虚拟机规范,来校验你加载进来的“.class”文件中的内容,是否符合指定的规范。)
  • 准备:Java虚拟机为类变量(static修饰的变量)、加载到内存中的类分配内存空间,设置默认初始值。
    •   示例代码:
public static int v=1; 在准备阶段中,v会被设置为0   在初始化的<clinit>中才会被设置为1
对于static final类型,在准备阶段就会被赋上正确的值: public static final  int v=1;
  • 解析::将符号引用替换为直接引用
    • 该阶段会把一些静态方法(符号引用,比如 main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态链接过 程(类加载期间完成),
    • 动态链接:是在程序运行期间完成的将符号引用替换为直接引用
3  初始化 (核心阶段)
初始化阶段是类加载最后一个阶段,前面的类加载阶段之后,除了在加载阶段可以自定义类加载器以外,其它操作都由 JVM 主导。到了初始阶段,才开始真正执行类中定义的 Java 程序代码。如: 在初始化阶段,JVM执行类的初始化语句, 为类的静态变量赋予用户给定的初始值,执行静态代码块 
什么时候会初始化一个类?
一般来说有以下一些时机:比如“new ReplicaManager()”来实例化类的对象了,此时就会触发类的加载到初始化的全过程,把这个类准备好,然后再实例化一个对象出来;(这里也说明了为什么 构造方法是在 静态代码块之后执行(先准备代码在实例化 ))
或者是包含“main()”方法的主类,必须是立马初始化的。
此外,这里还有一个非常重要的规则,就是如果初始化一个类的时候,发现他的父类还没初始化,那么必须先初始化他的父类

4 使用

5 卸载

http://www.cnblogs.com/ITtangtang/p/3978102.html

加载器的类型

类加载器类型总体来说可以分为以下几种:启动类加载器、其他类加载器。类的加载过程遵循双亲委派模型。
1、Bootstrap ClassLoader(启动类加载器)
    JVM启动,启动类加载器 加载 Java安装目录下jre 的 “lib”目录中的核心类库
/opt/apps/jdk1.8.0_251/jre/lib
--> rt.jar、charsets.jar等> rt.jar、charsets.jar等
2、Extension ClassLoader(扩展类加载器)
    JVM启动,通过扩展类加载器加载“lib/ext”目录
[root@iZ2zei4wx78lgr80odfj6eZ ext]# pwd# pwd
/opt/apps/jdk1.8.0_251/jre/lib/ext
3、Application ClassLoader(应用程序类加载器)
    加载ClassPath 环境变量所指定的路径中的类
4、自定义类加载器    
    根据自己需求进行类加载

类加载器初始化过程

参见类运行加载全过程图可知其中会创建JVM启动器实例sun.misc.Launcher。 
sun.misc.Launcher初始化使用了单例模式设计,保证一个JVM虚拟机内只有一个 sun.misc.Launcher实例。 
在Launcher构造方法内部,其创建了两个类加载器,分别是 sun.misc.Launcher.ExtClassLoader(扩展类加载器)和sun.misc.Launcher.AppClassLoader(应 用类加载器)。 
JVM默认使用Launcher的getClassLoader()方法返回的类加载器AppClassLoader的实例加载我们 的应用程序。

双亲委派模型

概述(向上寻找、向下委托)

类加载器收到类加载的请求,它首先不会自己去尝试加载这个类,而是 把这个请求委派给父类加载器完成。
每个类加载器都是如此,只有当父加载器在自己的搜索范围内找不到指定的类时(即ClassNotFoundException),
子加载器才会尝试自己去加载,这个过程为称为双亲委派模型。

AppClassLoader加载类的双亲委派机制源码

AppClassLoader 的loadClass方法最终会调用其父类ClassLoader的loadClass方法,
  • 1. 首先,检查一下指定名称的类是否已经加载过,如果加载过了,就不需要再加载,直接 返回。 
  • 2. 如果此类没有加载过,那么,再判断一下是否有父加载器;如果有父加载器,则由父加 载器加载(即调用parent.loadClass(name, false);).或者是调用bootstrap类加载器来加 载。
  • 3. 如果父加载器及bootstrap类加载器都没有找到指定的类,那么调用当前类加载器的 findClass方法来完成类加载。 
  • 对应代码位置://ClassLoader的loadClass方法,里面实现了双亲委派机制

为什么需要双亲委派模型

  • 保证类加载机制的安全性。
    • 防止病毒代码植入,自己写的java.lang.String.class类不会被加载,这样便可以防止核心 API库被随意篡改
  • 避免类的重复加载:
    • 当父亲已经加载了该类时,就没有必要子ClassLoader再加载一 次,保证被加载类的唯一性
  • 参考 : https://www.cnblogs.com/wxd0108/p/6681618.html

全盘负责委托机制 

  • “全盘负责”是指当一个ClassLoder装载一个类时,除非显示的使用另外一个ClassLoder,该类 所依赖及引用的类也由这个ClassLoder载入。

如何打破双亲委派模式

  • 覆写loadClass方法
    •  protected Class<?> loadClass(String name, boolean resolve)
    • 执行findClass()
      • 首先会使用自定义类加载器加载类, 不在向上委托, 直接由自己执行
    • 参考:https://www.cnblogs.com/ITPower/p/13211490.html

打破双亲委派模式的案例

  • tomcat类加载器
    • Common类加载器,加载Tomcat和Web应用都复用的类。
    • Catalina类加载器,加载Tomcat专有类(这些类在web应用中不可见)
    • Shared类加载器,加载所有Web应用都复用都类。(这些类tomcat中不可见)
    • WebappClassLoader:webapp私有的类加载器,只对当前webapp可见
  • Jsp类加载器,不同的jsp页面有不同的类加载器,方便实现jsp页面的热插拔。
  • 类加载机制原理
    • a. CommonClassLoader能加载的类都可以被Catalina ClassLoader和SharedClassLoader使用,从而实现了公有类库的共用

      b. CatalinaClassLoader和Shared ClassLoader自己能加载的类则与对方相互隔离

      c. WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离,多个WebAppClassLoader是同级关系

      d. 而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能

  • 为什么打破双亲委派模式?
    • 隔离性
      • 一个web应用可以部署多个应用程序,不同的应用程序可能会依赖同一个第三方类库的不同版本。
        • 因此需要保证每个应用程序的类库是独立的、相互隔离的。
      • web容器也有自己的类库,不能和应用程序的类库混淆,需要相互隔离
    • 共享性
      • 部署在同一个web容器中的相同类库的相同版本可以共享,否则,会有重复的类库被加载进JVM
    • 独立性
      • web容器支持jsp文件修改后不用重启,jsp文件也是要编译成.class文件的,支持HotSwap功能
  • tomcat如何打破双亲委派模式的?
    • 参考tomcat类加载机制 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用宝塔面板搭建Discuz并结合cpolar实现远程访问本地论坛

文章目录 前言1.安装基础环境2.一键部署Discuz3.安装cpolar工具4.配置域名访问Discuz5.固定域名公网地址6.配置Discuz论坛 前言 Crossday Discuz! Board&#xff08;以下简称 Discuz!&#xff09;是一套通用的社区论坛软件系统&#xff0c;用户可以在不需要任何编程的基础上&a…

京东大佬教你剖析软件测试的底层逻辑

写这篇文章&#xff0c;是希望把我的一些我认为是非常有价值的经验总结出来&#xff0c;能够帮助刚做测试不久的新同事&#xff0c;或者是测试经验丰富的老同事以共享。 希望我们可爱的新同事&#xff0c;准备要在测试领域耕耘的伙伴&#xff0c;能够通过我的文章了解到测试的底…

哪吒监控:开源、轻量、易用的服务器监控、运维工具(内附主题美化代码)

哪吒监控是一款开源、轻量、易用的服务器监控、运维工具,为用户提供了一系列强大的功能和便捷的操作方式。 一键安装:支持一键脚本安装面板和监控服务,适用于Linux、Windows、MacOS、OpenWRT等主流系统,让您轻松上手。 实时监控:能够同时监控多个服务器的系统状态,包括…

Linux --- 应用层 | HTTP | HTTPS

前言 前面写的TCP/UDP客户端在访问服务端的时候&#xff0c;需要输入ip地址和端口号才可以访问&#xff0c; 但在现实中&#xff0c;我们访问一个网站是直接输入的一个域名&#xff0c;而不是使用的ip地址端口号。 比如在访问百度 https://www.baidu.com/的时候&#xff0c; …

Linux安装

安装方式介绍 Linux系统的安装方式&#xff0c;主要包含以下两种&#xff1a; 方式概述场景物理机安装直接将操作系统安装到服务器硬件上企业开发中&#xff0c;我们使用的服务器基本都是采用这种方式虚拟机安装通过虚拟机软件安装我们在学习阶段&#xff0c;没有自己服务器&a…

GraphQL

从表中查询10条数据 {user_info(_limit: 100) {idname} }根据id查询数据 {user_info(_where: {id: 1727515006802587648}_order_by: {create_time: _desc}_limit: 10) {idname} }外键联表查询(特别注意写法:update_by.id): {speaker_info(update_by.id: {_eq: 1729043650301…

修改MonkeyDev默认配置适配Xcode15

上一篇文章介绍了升级Xcode15后,适配MonkeyDev的一些操作,具体操作可以查看:Xcode 15 适配 MonkeyDev。 但是每次新建项目都要去修改那些配置,浪费时间和精力,这篇文章主要介绍如何修改MonkeyDev的默认配置,做到一次修改永久生效。 MonkeyDev的默认安装路径是在/opt/Mo…

STM32第九课:ADC单通道模数转换

一、ADC简介 ADC是Analog-to-DigitalConverter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。 STM32f103 系列有3个ADC&#xff0c;精度为12位&#xf…

vite项目修改node_modules

问题详情 在使用某个依赖的时候遇到了bug&#xff0c;提交issue后不想一直等待到作者更新版本&#xff0c;所以寻求临时自己解决 问题解决 在node_modules里找到需要修改的依赖&#xff0c;修改想要修改的代码 修改后记得保存 然后在node_modules里找到.vite文件夹&#x…

Java8 CompletableFuture异步编程-入门篇

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 前言 1、Future vs CompletableFuture 1.1 准备工作 1.2 Future 的局限性 …

01_Maven

文章目录 Maven安装MavenMaven的工作流程配置MavenMaven的使用module和project的关系如何用Maven导包 如何用Maven进行项目构建指令介绍clean指令compile指令package指令install指令 Maven的依赖管理如何导包scope作用域依赖传递依赖冲突 使用Maven开发项目Junit如何使用Junit …

xss.pwnfunction.com靶机 Warmups

通关要求弹出警告框alert(1337) 没有用户交互 不能使用外链接 在chrome中测试 Ma Spaghet! 通过分析代码我们可以看到它直接用innerHTML将接收的内容赋值 但是我们不能使用<script>标签因为&#xff1a;HTML 5 中指定不执行由 innerHTML 插入的 <script> 标签。 所…

字符串标记高亮脚本

源码 #!/bin/bash # usage: # echo hhh|mark str [font_color] [background_color] # font_color and background_color is optional, default is black&whiterp_str$1 f_color30 b_color47if [ "${f_color}a" "a" ]; thenf_color30 fiif [ "${…

985硕的4家大厂实习与校招经历专题分享(part1)

先简单介绍一下我的个人经历&#xff1a; 985硕士24届毕业生&#xff0c;实验室方向:CV深度学习 就业&#xff1a;工程-java后端 关注大模型相关技术发展 校招offer: 阿里巴巴 字节跳动 等10 研究生期间独立发了一篇二区SCI 实习经历:字节 阿里 京东 B站 &#xff08;只看大厂…

Stable Diffusion 解析:探寻 AI 绘画背后的科技神秘

AI 绘画发展史 在谈论 Stable Diffusion 之前&#xff0c;有必要先了解 AI 绘画的发展历程。 早在 2012 年&#xff0c;华人科学家吴恩达领导的团队训练出了当时世界上最大的深度学习网络。这个网络能够自主学习识别猫等物体&#xff0c;并在短短三天时间内绘制出了一张模糊但…

(黑马出品_04)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

&#xff08;黑马出品_04&#xff09;SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术异步通信 今日目标1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯 1.2.技术对比 2.快速入门2.1.安装RabbitMQ2.1.1.单机部署(1).下载镜像方式…

Amazon Bedrock 上的新一代 Anthropic 模型 Claude 3

如您所知&#xff0c;Amazon Bedrock 是利用基础模型 (FM) 构建生成式 AI 解决方案的最简单的途径&#xff0c;其中包括使用 Anthropic 的先进模型 Claude。而如今&#xff0c;新一代 Claude 模型已经到来。到目前为止&#xff0c;我已经制作了 3 个单独视频来介绍 Claude 3 的…

图论练习5

Going Home Here 解题思路 模板 二分图最优匹配&#xff0c;前提是有完美匹配&#xff08;即存在一一配对&#xff09;左右集合分别有顶标&#xff0c;当时&#xff0c;为有效边&#xff0c;即选中初始对于左集合每个点&#xff0c;选择其连边中最优的&#xff0c;然后对于每…

Unity 给刚体一个力或速度

创建平面和小球&#xff0c;给力或给速度让其弹起 给小球挂载刚体&#xff08;Rigibdody&#xff09;和脚本 &#xff08;力是累计或者衰减的&#xff0c;直接给速度就是赋值&#xff0c;但如果速度就和力类似了&#xff09; using System.Collections; using System.Collect…

开发手札:unity2022+vscode1.87联合开发

不得不说&#xff0c;时间的力量是很强大的&#xff0c;同时熵增理论适用于任何地方。 在现在的公司干了五年多了&#xff0c;五年前配置的内网开发机&#xff0c;i7 870016g1t hddgtx1080已经卡爆了&#xff0c;特别是硬盘掉速严重&#xff0c;开机开软件没有一两分钟都…