首页 > 其他分享 >JVM虚拟机系统性学习-类加载子系统

JVM虚拟机系统性学习-类加载子系统

时间:2023-12-13 13:32:46浏览次数:32  
标签:初始化 变量 虚拟机 JVM 字节 子系统 加载

类加载子系统

JVM 架构如下图,接下来将从类加载子系统、运行时数据区来逐步讲解 JVM 虚拟机

JVM虚拟机系统性学习-类加载子系统_类加载器

类加载的时机

类加载的时机主要有 4 个:

  • 遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时,如果对应的类没有初始化,则要先进行初始化
  • new 关键字创建对象时
  • 读取或设置一个类型的静态字段时(被 final 修饰、已在编译器将结果放入常量池的静态类型字段除外)
  • 调用一个类型的静态方法的时候
  • 对类进行 反射调用
  • 初始化一个类的时候,如果其父类未初始化,要先初始化其父类
  • 虚拟机启动时,要先加载主类(程序入口)

类加载过程

类的生命周期如下图:

JVM虚拟机系统性学习-类加载子系统_初始化_02

  • 加载
  1. 通过二进制字节流加载 class 文件
  2. 创建该 class 文件在方法区的运行时数据结构
  3. 创建字节码对象 Class 对象
  • 链接
  1. 验证:目的在于确保 class 文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性
    主要包括四种验证:文件格式验证、元数据验证、字节码验证、符号引用验证
  2. 准备:为类变量(即静态变量)分配内存并且设置类变量的默认初始值,即零值。
    这里不包含用 final 修饰的 static 变量,因为 final 修饰的变量在编译为 class 字节码文件的时候就会分配了,准备阶段会显式初始化
    这里不会为实例变量分配初始化,类变量会分配在方法区,而实例变量是会随着对象一起分配到 Java 堆中
  3. 解析:将常量池内的符号引用转换为直接引用的过程
    事实上,解析操作往往会伴随着 JVM 在执行完初始化之后再执行
    符号引用就是一组符号来描述所引用的莫表。符号引用的字面量形式明确定义在《java虚拟机规范》的Class 文件格式中。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。
    解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。
  • 初始化
    虚拟机在初始化阶段才真正开始执行类中编写的 Java 程序代码
    初始化阶段就是执行类构造器 <clinit>() 方法的过程,<clinit>() 是 Javac 编译器自动生成的,该方法由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并生成的,如果一个类中没有静态代码块, 也没有变量赋值的动作,那么编译器可以不为这个类生成 <clinit>() 方法

类加载器

JVM 中类加载是通过类加载器来完成的

JVM虚拟机系统性学习-类加载子系统_类加载器_03

  • 启动类加载器(Bootstrap ClassLoader):
  • 负责加载 JAVA_HOME\lib 目录中的,或通过 -Xbootclasspath 参数指定路径中的,且被虚拟机认可(按文件名识别,如rt.jar)的类。由 C++ 实现,不是 ClassLoade r的子类
  • 扩展类加载器(Extension ClassLoader):
  • 负责加载 JAVA_HOME\lib\ext 目录中的,或通过 java.ext.dirs 系统变量指定路径中的类库。
  • 应用程序类加载器(Application ClassLoader):
  • 负责加载用户路径 classpath 上的类库
  • 自定义类加载器(User ClassLoader):
  • 作用:JVM自带的三个加载器只能加载指定路径下的类字节码,如果某些情况下,我们需要加载应用程序之外的类文件,就需要用到自定义类加载器

双亲委派机制

加载类的class文件时,Java虚拟机采用的是双亲委派机制,即把请求交给父类加载器去加载

工作原理:

  1. 如果一个类加载器收到了类加载请求,他并不会自己先去加载,而是把这个请求委托给父类的加载器去执行
  2. 如果父类加载器也存在其父类加载器,则继续向上委托
  3. 如果父类加载器可以完成类加载任务,就成功返回;如果父类加载器无法完成类加载任务,则会由自家在其尝试自己去加载

优势:

  1. 避免类的重复加载
  2. 保护程序安全,防止核心API被篡改(例如,如果我们自定义一个java.lang.String类,然后我们去new String(),我们会发现创建的是jdk自带的String类,而不是我们自己创建的String类)

为什么还需要破坏双亲委派?

  • 在实际应用中,可能存在 JDK 的基础类需要调用用户代码,例如:SPI 就打破双亲委派模式(打破双亲委派意味着上级委托下级加载器去加载类)
  • 比如,数据库的驱动,Driver 接口定义在 JDK 中,但是其实现由各个数据库的服务上提供,由系统类加载器进行加载,此时就需要 启动类加载器 委托子类加载器去加载 Driver 接口的实现

标签:初始化,变量,虚拟机,JVM,字节,子系统,加载
From: https://blog.51cto.com/u_16186397/8801739

相关文章

  • PCI总线子系统 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/PCI/index.htmlPCI总线子系统如何编写LinuxPCI驱动程序1.1.PCI驱动程序的结构1.2.pci_register_driver()调用1.3.如何手动查找PCI设备1.4.设备初始化步骤1.5.PCI设备关闭1.6.如何访问PCI配置空间1.7.其他有趣的函数1.......
  • 配置VMware令主机与虚拟机位于局域网同一网段
    1.VMWare版本2.宿主机信息3.虚拟机信息很顺利,没有遇到问题。参考:https://blog.csdn.net/weixin_45467056/article/details/112930163......
  • GPIO子系统驱动程序 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/gpio/drivers-on-gpio.htmlGPIO子系统驱动程序在Linux内核中,有许多标准的GPIO任务的驱动程序,它们提供了适当的内核空间和用户空间的API/ABI,并且可以通过硬件描述(如设备树或ACPI)与其他内核子系统轻松连接:leds-gpio:driver......
  • [linux] [Centos8] 一台虚拟机的安装配置全过程
    今年7月的时候刚学linux,写过几篇配置,结果学得越多才发现已经过时了,这两天重装的时候被自己的文章搞晕了......
  • PINCTRL(PIN CONTROL)子系统 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/pin-control.htmlPINCTRL(PINCONTROL)子系统本文概述了Linux中的pincontrol子系统。该子系统涉及以下内容:枚举和命名可控制的引脚引脚、Pads、Fingers(等)的复用,请参见下文了解详情配置引脚、Pads、Fingers(等),例如软件控制......
  • PHY 子系统 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/driver-api/phy/phy.htmlPHY子系统作者[email protected]本文档解释了通用PHY框架以及提供的API,以及如何使用。简介PHY是物理层的缩写。它用于将设备连接到物理介质,例如,USB控制器具有PHY来提供序列化、反序列......
  • 虚拟机突然连接不上xshell的解决方案
    今天我打开虚拟机和xshell的时候,发现我的node1连接不上xshell,但是node2、node3依旧可以链接,我在网上找了很多方法,但是是关于全部虚拟机连接不上xshell,但是,我只有一个连接不上,然后我发现我在虚拟机上输入ifconfig的时候显示它不显示我虚拟机的ip地址,查找后我发现是我的ens33这个......
  • VMware workstation 17安装虚拟机ubuntu原始镜像.iso注意事项
    1在安装虚拟机向导对话框,命名虚拟机位置:A虚拟机名称:这里选ubuntu64位B位置(L):该选项要注意:安装时会清除该位置的内容,并且安装完后打开该位置就全部是虚拟机的文件了,跟windows的C盘一样,不能放其他文件了。我选择的位置时E盘,安装完后,打开E盘,里面很多ubuntu......
  • 支持优先级继承的RT-mutex子系统
    https://www.kernel.org/doc/html/v6.6/locking/rt-mutex.htmlRT-mutex子系统支持PIRT-mutexes与优先级继承一起使用,以支持PI-futexes,从而使pthread_mutex_t支持优先级继承属性(PTHREAD_PRIO_INHERIT)。[有关PI-futexes的更多详细信息,请参见轻量级PI-futexes。]这项技术是在-rt......
  • 通用互斥子系统 【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/locking/mutex-design.html通用互斥子系统由[email protected]发起由[email protected]更新互斥锁是什么?在Linux内核中,互斥锁指的是一种特定的锁原语,它在共享内存系统上强制进行串行化,而不仅仅是指学术界......