面试题解,JVM中的“类加载”剖析

news2025/1/7 13:19:26

一、JVM类加载机制说一下

其中,从加载到初始化就是我们的类加载阶段,我们逐一来分析

加载

“加载 loading”是整个类加载(class loading)过程的一个阶段,加载阶段JVM需要完成以下 3 件事情:

  • 1)通过一个类的全限定名来获取定义此类的二进制字节流。
  • 2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构(Class,Field,Method)。
  • 3)在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。

注意:

  • 加载的字节码来源,不一定非得是class文件,可以是符合字节码规范的任意地方,甚至二进制流等
  • 从字节码到内存,是由加载器(ClassLoader)完成的

验证

  • 1、文件格式验证(版本号,是不是CAFEBABYE开头,..........
  • 2、元数据验证(验证属性、字段、类关系、方法等是否合规)
  • 3、字节码验证
  • 4、符号引用验证
  • 等等...

准备

为class中定义的各种类变量(静态变量)分配内存,并赋初始值,注意是对应类型的初始值,赋具体值在后面的初始化阶段。注意!即便是static变量,它在这个阶段初始化进内存的依然是该类型的初始值(零默认值等)!而不是用户代码里的初始值。

举例:

//类变量:在准备阶段为它开辟内存空间,但是它是int的初始值,也就是 0,而真正123的赋值,是在下面的初始化阶段 
public static int a = 123; 

//类成员变量(实例变量)的赋值是在类对象被构造时才会赋值 
public String address = "北京" 

//final修饰的类变量,编译成字节码后,是一个ConstantValue类型,在准备阶段,直接给定值123,后期也没有二次初始化一说 
public static final int b = 123;

解析

将常量池内的符号引用替换为直接引用的过程。

符号引用是以一组描述符(如类名、字段名和方法签名等)来表示的,而直接引用则是可以直接指向目标实体(如类、字段或方法)的具体内存地址或偏移量。

初始化

类加载的最后一个步骤,经过这个步骤后,类信息完全进入了jvm内存,直到它被垃圾回收器回收

前面几个阶段都是JVM来搞定的。我们也干涉不了,从代码上只能遵从它的语法要求。而这个阶段,是初始化赋值,java虚拟机才真正开始执行类中编写的java程序代码,将主导权移交给应用程序。

所以在这个阶段是执行类中和static相关的所有事,比如静态代码块,静态变量赋值等

那么这些事都会经过javac编译器自动将这些事情编到<clinit>函数

<clinit> 函数是由编译器自动收集类中的所有静态变量的赋值动作和静态语句块( static 代码块)中的语句合并产生的。

<clinit> 函数与类的构造函数(虚拟机视角的 <init> 函数)是不同的, <init> 函数是在运行期创建对象时才执行,而 <clinit> 在类加载的时候就执行了。

虚拟机能保障父类的 <clinit> 函数优先于子类 <clinit> 函数的执行

在 <clinit> 函数中会对类变量赋具体的值,也就是我们说的:

public static int a = 123; 1

这行代码的123才真正赋值完成。

二、双亲委派机制的过程及作用,三种类加载器,加载过程,双亲委派机制能打破吗?

三种类加载器

先来说一下三种类加载器,类加载器做的事情就是上面 5 个步骤的事(加载、验证、准备、解析、初始化),java提供了3个系统加载器,分别是 Bootstrap ClassLoader、ExtClassLoader 、AppClassLoader

每个类加载器加载不同路径下的类

Bootstrp加载器是用 C++ 语言写的,它在Java虚拟机启动后初始化,它主要负责加载以下路径的文件:

  • %JAVA_HOME%/jre/lib/*.jar
  • %JAVA_HOME%/jre/classes/*
  • -Xbootclasspath 参数指定的路径

ExtClassLoader 是用 Java 写的,具体来说就是sun.misc.Launcher$ExtClassLoader,主要加载:

  • %JAVA_HOME%/jre/lib/ext/*
  • ext 下的所有 classes 目录
  • java.ext.dirs 系统变量指定的路径中类库

AppClassLoader 也是用Java写成的,它的实现类是sun.misc.Launcher$AppClassLoader ,另外我们知道 ClassLoader 中有个getSystemClassLoader 方法,此方法返回的就是它。

  • 负责加载 -classpath 所指定的位置的类或者是jar文档
  • 也是Java程序默认的类加载器

双亲委派模型

双亲委派模型的核心就是,当前类加载器在加载一个类时,先委派给其父加载器,如果父加载器已经加载过了,那么自己就不再加载了。

具体一点来说:

        类加载器加载某个类的时候,因为有多个加载器,甚至可以有各种自定义的,他们呈父子关系。这给人一种印象,子类的加载会覆盖父类,其实恰恰相反!

        与普通类继承属性不同,类加载器会优先调父类的 loadClass 方法,如果父类能加载,直接用父类的,否则最后一步才是自己尝试加载,从源代码上可以验证。

那为什么这么设计呢?

双亲委派模型作用

避免重复加载、 核心类篡改

        采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父加载器已经加载了该类时,就没有必要子加载器再加载一次。

        其次是考虑到安全因素,java核心api中定义类型不会被随意替换,假设通过网络传递一个名为 java.lang.Integer 的类,通过双亲委派模型传递到启动类加载器,而启动类加载器发现这个名字的类,发现该类已被加载,就不会重新加载网络传递过来的 java.lang.Integer ,而直接返回已加载过的Integer.class ,这样便可以防止核心API库被随意篡改。

双亲委派能否打破

比如:Tomcat的 webappClassLoader 加载web应用下的class文件,不会传递给父类加载器,

问题:tomcat的类加载器为什么要打破该模型?

首先一个tomcat启动后是会起一个jvm进程的,它支持多个web应用部署到同一个tomcat里,为此

  • 1、对于不同的web应用中的class和外部jar包,需要相互隔离,不能因为不同的web应用引用了相同的jar或者有相同的class导致一个加载成功了另一个加载不了。
  • 2、web容器支持jsp文件修改后不用重启,jsp文件也是要编译成.class文件的,每一个jsp文件对应一个JspClassLoader,它的加载范围仅仅是这个jsp文件所编译出来的那一个.class文件,当Web容器检测到jsp文件被修改时,会替换掉目前JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的热部署功能。

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

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

相关文章

vue路由模式面试题

vue路由模式 1.路由的模式有哪些?有什么区别? history和hash模式 区别: 1.表现的形态不同: 在地址栏url中:hash模式中带有**#**号,history没有 2.请求错误时表现不同: 在hash模式中,对于404地址请求时,不会进行请求 但是在history模式中,对于404请求时,仍然会进行请求…

构建一个rust生产应用读书笔记7-确认邮件3

设计架构思路 从前面的学习过程中&#xff0c;我们从单一文件测试套件发展到模块化测试套件&#xff0c;并构建了一套强大的辅助工具&#xff0c;这是一个非常重要的进展。个人认为测试代码和应用代码一样&#xff0c;是一个持续进化的过程。随着项目的不断成长&#xff0c;测…

默认ip无法访问,利用dhcp功能获取ip进行访问的方法

应用场景&#xff1a; ac的默认ip如192.168.1.1在pc与ac的eth2以后网口直连无法ping通&#xff0c;而且pc改为dhcp自动获取ip也获取不到ip地址&#xff0c;无法进行web配置和命令行操作。 原因是ac或其他设备被修改了默认ip或者对应端口所属vlanid&#xff0c;现在的端口vlan…

redis的集群模式与ELK基础

一、redis的集群模式 1.主从复制 &#xff08;1&#xff09;概述 主从模式&#xff1a;这是redis高可用的基础&#xff0c;哨兵和集群都是建立在此基础之上。 主从模式和数据库的主从模式是一样的&#xff0c;主负责写入&#xff0c;然后把写入的数据同步到从服务器&#xff…

大脑特训,自信 “满格”

编辑&#xff1a;念小艺 在追求自信的漫漫长路上&#xff0c;诸多因素如同闪耀的星光&#xff0c;为人们指引着方向。保持良好的饮食习惯&#xff0c;让身体摄取充足且均衡的营养&#xff0c;为精神的饱满提供坚实后盾&#xff1b;持续投身于锻炼之中&#xff0c;在挥洒汗水的…

渗透测试-非寻常漏洞案例

声明 本文章所分享内容仅用于网络安全技术讨论&#xff0c;切勿用于违法途径&#xff0c;所有渗透都需获取授权&#xff0c;违者后果自行承担&#xff0c;与本号及作者无关&#xff0c;请谨记守法. 此文章不允许未经授权转发至除先知社区以外的其它平台&#xff01;&#xff0…

计算机的发展、计算机基本组成原理

计算机系统 软件 硬件 硬件的发展 软件的发展 低级语言&#xff1a;机器语言、汇编语言 一、早期冯诺依曼机的结构 存储程序&#xff1a;将指令以二进制代码事先输入计算机的主存储器 在计算机系统软件和硬件是等效的 软件&#xff1a;数据 程序 硬件&#xff1a; 存储器、…

公共数据授权运营系统建设手册(附下载)

在全球范围内&#xff0c;许多国家和地区已经开始探索公共数据授权运营的路径和模式。通过建立公共数据平台&#xff0c;推动数据的开放共享&#xff0c;促进数据的创新应用&#xff0c;不仅能够提高政府决策的科学性和公共服务的效率&#xff0c;还能够激发市场活力&#xff0…

[极客大挑战 2019]HardSQL 1

看了大佬的wp&#xff0c;没用字典爆破&#xff0c;手动试出来的&#xff0c;屏蔽了常用的关键字&#xff0c;例如&#xff1a;order select union and 最搞的是&#xff0c;空格也有&#xff0c;这个空格后面让我看了好久&#xff0c;该在哪里加括号。 先传入1’ 1试试&#…

iOS 逆向学习 - iOS Architecture Cocoa Touch Layer

iOS 逆向学习 - iOS Architecture Cocoa Touch Layer 一、Cocoa Touch Layer 简介二、Cocoa Touch Layer 的核心功能1. UIKit2. Event Handling&#xff08;事件处理&#xff09;3. Multitasking&#xff08;多任务处理&#xff09;4. Push Notifications&#xff08;推送通知&…

STM32烧写失败之Contents mismatch at: 0800005CH (Flash=FFH Required=29H) !

一&#xff09;问题&#xff1a;用ULINK2给STM32F103C8T6下载程序&#xff0c;下载方式设置如下&#xff1a; 出现下面两个问题&#xff1a; 1&#xff09;下载问题界面如下&#xff1a; 这个错误的信息大概可以理解为&#xff0c;在0x08000063地址上读取到flash存储为FF&am…

使用命令行管理git项目

# 初始化一个新的Git仓库 git init # 添加文件到暂存区 git add <file> # 提交暂存区的更改到仓库 git commit -m "commit message" # 查看当前仓库的状态 git status # 查看提交历史 git log # 查看文件的改动 git diff <file> # 创建一个新…

论文笔记PhotoReg: Photometrically Registering 3D Gaussian Splatting Models

1.abstract 最近推出的3D高斯飞溅(3DGS)&#xff0c;它用多达数百万个原始椭球体来描述场景&#xff0c;可以实时渲染。3DGS迅速声名鹊起。然而&#xff0c;一个关键的悬而未决的问题仍然存在&#xff1a;我们如何将多个3DG融合到一个连贯的模型中&#xff1f;解决这个问题将使…

javaEE-网络原理-1初识

目录 一.网络发展史 1.独立模式 2.网络互联 二.局域网LAN 1.基于网线直连&#xff1a; 2.基于集线器组件&#xff1a; 3.基于交换机组件&#xff1a; 4.基于交换机和路由器组件 ​编辑 三、广域网WAN 四、网络通信基础 1.ip地址 2.端口号&#xff1a; 3.协议 4.五…

电子电气架构 --- 整车整车网络管理浅析

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…

xml格式化(3):增加头部声明

前言 这篇文章&#xff0c;是用来增加头部声明。 正文 from lxml import etreedef pretty_print(element, level0, indent" "):result ""# 判断元素是否为注释节点if isinstance(element, etree._Comment):result f"{indent * level}<!--{el…

STM32 高级 物联网通讯之LoRa通讯

目录 LoRa通讯基础知识 常见的3种通讯协议 远距离高速率的传输协议 近距离高速率传输技术 近距离低功耗传输技术 低功耗广域网 采用授权频段技术 非授权频段 LoRa简介 LoRa的特点 远距离 低功耗 安全 标准化 地理定位 移动性 高性能 低成本 LoRa应用 LoRa组…

【FlutterDart】 拖动改变 widget 的窗口尺寸大小GestureDetector~简单实现(10 /100)

上效果 预期的是通过拖动一条边界线改变窗口大小&#xff0c;类似vscode里拖动效果。这个是简单的拖动实现 上代码&#xff1a; import package:flutter/material.dart;class MyDraggableViewDemo extends StatelessWidget {const MyDraggableViewDemo({super.key});override…

Luma AI 简单几步生成视频

简单几步生成视频 登录我们的 AceDataPlatform 网站&#xff0c;按照下图所示即可生成高质量的视频&#xff0c;同时&#xff0c;我们也提供了简单易用的 API 方便集成调用&#xff0c;可以查看 Luma API了解详情 技术介绍 我们使用了 Luma 的技术&#xff0c;实现了上面的图…

如何免费解锁 IPhone 网络

您是否担心 iPhone 上的网络锁定&#xff1f;如果您的 iPhone 被锁定到特定运营商&#xff0c;解锁它可以连接到不同的运营商。好吧&#xff0c;我们为您准备了一份指南。 iPhone运营商免费解锁将是小菜一碟。在我们的解锁运营商 iphone 免费指南中。我们为您提供了一份简介&am…