java-JVM 类加载机制

JVM 类加载机制

  1. JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程。
    在这里插入图片描述
1.1. 加载
  • 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的入口。注意这里不一定非得要从一个 Class 文件获取,这里既可以从 ZIP 包中读取(比如从 jar 包和 war 包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将 JSP 文件转换成对应的 Class 类)。
1.2. 验证
  • 这一阶段的主要目的是为了确保 Class 文件的字节流中包含的信息是否符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。
1.3. 准备
  • 准备阶段是正式为类变量分配内存并设置类变量的初始值阶段,即在方法区中分配这些变量所使用的内存空间。注意这里所说的初始值概念,比如一个类变量定义为:
    • public static int v = 8080;
  • 实际上变量 v 在准备阶段过后的初始值为 0 而不是 8080,将 v 赋值为 8080 的 put static 指令是
    程序被编译后,存放于类构造器方法之中。
  • 但是注意如果声明为:
    • public static final int v = 8080;
  • 在编译阶段会为 v 生成 ConstantValue 属性,在准备阶段虚拟机会根据 ConstantValue 属性将 v
    赋值为 8080。
1.4. 解析
  • 解析阶段是指虚拟机将常量池中的符号引用替换为直接引用的过程。符号引用就是 class 文件中的:
  1. CONSTANT_Class_info
  2. CONSTANT_Field_info
  3. CONSTANT_Method_info
    等类型的常量。
1.5. 符号引用
  • 符号引用与虚拟机实现的布局无关,引用的目标并不一定要已经加载到内存中。各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,因为符号引用的字面量形式明确定义在 Java 虚拟机规范的 Class 文件格式中。
1.6. 直接引用
  • 直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在。
1.7. 初始化
  • 初始化阶段是类加载最后一个阶段,前面的类加载阶段之后,除了在加载阶段可以自定义类加载器以外,其它操作都由 JVM 主导。到了初始阶段,才开始真正执行类中定义的 Java 程序代码。
1.8. 类构造器
  • 初始化阶段是执行类构造器方法的过程。方法是由编译器自动收集类中的类变量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证子方法执行之前,父类的方法已经执行完毕,如果一个类中没有对静态变量赋值也没有静态语句块,那么编译器可以不为这个类生成()方法。
  • 注意以下几种情况不会执行类初始化:
  1. 通过子类引用父类的静态字段,只会触发父类的初始化,而不会触发子类的初始化。
  2. 定义对象数组,不会触发该类的初始化。
  3. 常量在编译期间会存入调用类的常量池中,本质上并没有直接引用定义常量的类,不会触发定义常量所在的类。
  4. 通过类名获取 Class 对象,不会触发类的初始化。
  5. 通过 Class.forName 加载指定类时,如果指定参数 initialize 为 false 时,也不会触发类初始化,其实这个参数是告诉虚拟机,是否要对类进行初始化。
  6. 通过 ClassLoader 默认的 loadClass 方法,也不会触发初始化动作。

2. 类加载器

  • 虚拟机设计团队把加载动作放到 JVM 外部实现,以便让应用程序决定如何获取所需的类,JVM 提
    供了 3 种类加载器:
2.1. 启动类加载器(Bootstrap ClassLoader)
  1. 负责加载 JAVA_HOME\lib 目录中的,或通过-Xbootclasspath 参数指定路径中的,且被虚拟机认可(按文件名识别,如 rt.jar)的类。
2.2. 扩展类加载器(Extension ClassLoader)
  1. 负责加载 JAVA_HOME\lib\ext 目录中的,或通过 java.ext.dirs 系统变量指定路径中的类库。
2.3. 应用程序类加载器(Application ClassLoader):
  1. 负责加载用户路径(classpath)上的类库。
    JVM 通过双亲委派模型进行类的加载,当然我们也可以通过继承 java.lang.ClassLoader实现自定义的类加载器。
    在这里插入图片描述

3. 双亲委派

  • 当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。采用双亲委派的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object,不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,这样就保证了使用不同的类加载器最终得到的都是同样一个 Object 对象。
    在这里插入图片描述

4. OSGI( 动态模型系统)

  • OSGi(Open Service Gateway Initiative),是面向 Java 的动态模型系统,是 Java 动态化模块化系统的一系列规范。
4.1. 动态改变构造
  • OSGi 服务平台提供在多种网络设备上无需重启的动态改变构造的功能。为了最小化耦合度和促使这些耦合度可管理,OSGi 技术提供一种面向服务的架构,它能使这些组件动态地发现对方。
4.2. 模块化编程与热插拔
  • OSGi 旨在为实现 Java 程序的模块化编程提供基础条件,基于 OSGi 的程序很可能可以实现模块级的热插拔功能,当程序升级更新时,可以只停用、重新安装然后启动程序的其中一部分,这对企业级程序开发来说是非常具有诱惑力的特性。
  • OSGi 描绘了一个很美好的模块化开发目标,而且定义了实现这个目标的所需要服务与架构,同时也有成熟的框架进行实现支持。但并非所有的应用都适合采用 OSGi 作为基础架构,它在提供强大功能同时,也引入了额外的复杂度,因为它不遵守了类加载的双亲委托模型。

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

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

相关文章

如何在Moonriver网络上向社区代表委托投票权利

我们之前介绍了「社区代表」这一概念,想必大家对社区代表在治理中扮演的角色和地位有了一定的了解。 本文将介绍如何将您的投票权利委托给社区代表。请注意,在委托Token给社区代表这一过程中,并非将您的Token转移给任何人,而且此…

Leetcode67 二进制求和

给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 代码 class Solution {public String addBinary(String a, String b) {StringBuilder res new StringBuilder();int carry 0;int i a.length() - 1, j b.length() - 1;while(i > 0 || j &…

代驾系统:革新出行体验的智能伙伴

在现代社会,出行方式正在经历着一场革命,而代驾系统正是这场革命中的一位智能伙伴。通过结合智能科技和出行需求,代驾系统为我们带来了便捷、安全、个性化的出行体验。本文将介绍代驾系统的工作原理,并通过Python代码演示其基本功…

ansible(2)-- ansible常用模块

部署ansible:ansible(1)-- 部署ansible连接被控端_luo_guibin的博客-CSDN博客 目录 一、ansible常用模块 1.1 ping 1.2 command 1.3 raw 1.4 shell 1.5 script 1.6 copy 1.7 template 1.8 yum 11.0.1.13 主控端(ansible)11.0.1.12 被控端(k8s…

【通俗易懂】如何使用GitHub上传文件,如何用git在github上传文件

目录 创建 GitHub 仓库 使用 Git 进行操作 步骤 1:初始化本地仓库 步骤 2:切换默认分支 步骤 3:连接到远程仓库 步骤 4:获取远程更改 步骤 5:添加文件到暂存区 步骤 6:提交更改 步骤 7&#xff1a…

(排序) 剑指 Offer 45. 把数组排成最小的数 ——【Leetcode每日一题】

❓ 剑指 Offer 45. 把数组排成最小的数 难度:中等 输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。 示例 1: 输入: [10,2] 输出: “102” 示例 2: 输入: [3,30,34,5,9] 输出: “3033459”…

Kafka 集群搭建过程

前言 跟着尚硅谷海哥文档搭建的Kafka集群环境,在此记录一下,侵删 注意:博主在服务器上搭建环境的时候使用的是一个服务器,所以这篇博客可能会出现一些xsync分发到其他服务器时候的错误,如果你在搭建的过程中出现了错…

只考一门数据结构,计算机学硕复录比1:1的山东双非学校考情分析

青岛理工大学 考研难度(☆) 内容:23考情概况(拟录取和复试分析)、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1420字,预计阅读:3分钟 2023考情概况 青岛理工…

多维时序 | MATLAB实现KOA-CNN-BiGRU-Attention多变量时间序列预测

多维时序 | MATLAB实现KOA-CNN-BiGRU-Attention多变量时间序列预测 目录 多维时序 | MATLAB实现KOA-CNN-BiGRU-Attention多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现KOA-CNN-BiGRU-Attention多变量时间序列预测,KOA-…

IntelliJ IDEA maven配置,设置pom.xml的配置文件

IntelliJ IDEA项目,选择 文件 设置,弹窗 构建、执行、部署 构建工具 Maven就可以 maven配置好以后,在pom.xml的配置文件中就可以设置对应的jar包了,这样构建的时候自动需要的jar,在项目中导入即 需要的jar包设置在po…

SpringMVC 反射型跨站点脚本攻击

解决方案&#xff1a; 服务端校验&#xff0c;添加拦截器 配置web,xml <filter><filter-name>xssFilter </filter-name><filter-class>com.fh.filter.XssFilter </filter-class></filter> XssFilter package com.fh.filter;import com…

Spring boot(一)

Spring Boot是一个构建在Spring框架顶部的项目。它提供了一种简便&#xff0c;快捷的方式来设置&#xff0c;配置和运行基于Web的简单应用程序。 它是一个Spring模块&#xff0c;提供了 RAD(快速应用程序开发)功能。它用于创建独立的基于Spring的应用程序&#xff0c;因为它需…