【类加载机制深度解析】,附带学习经验

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【类加载机制深度解析】,附带学习经验


  1. 获取到ClassLoader后调用loadClass(“A”)方法加载运行的类A
  2. 加载完成执行A类的main方法
  3. 程序运行结束
  4. JVM销毁

loadClass的类加载过程

===================

===================================================================================================================================================================================================

加载 ----> 验证 ----> 准备 ----> 解析 ----> 初始化 ----> 使用 ----> 卸载

谈及比较多的是前五个

  • **加载:**我们说jvm执行的java字节码,编译后在磁盘上,总得读取这个字节码文件吧 ,通过啥读 IO呗 , 所以第一步肯定是加载字节码文件。
  • 验证:JVM总不能说读到啥就直接运行了吧,你外面有个A.class 里面是一堆JVM规范不认识的内容,也执行不了啊 。 符合JVM规范才能执行后续的步骤,所以第二步是 校验字节码文件的正确性。
  • 准备:给类的静态变量分配内存,并赋予默认值。 我们的类里,可能会包含一些静态变量吧 。 比如 public static final int a = 12; 得给a分配个默认值 0 ,再比如 public static User user = new User(); 给 static的变量 User分配内存,并赋默认值null (final修饰的常量,直接赋值)。
  • 解析:这个地方不是很好理解, 解析是什么意思呢?将符号引用替换为直接引用。 符号引用 ? 直接引用? what ? 我们的类的静态方法,比如main方法,其实在Java中有个叫法 都是叫符号 。 这个阶段就会吧,一些静态方法(符号引用,比如刚才说的main方法)替换为指向数据所存内存的指针或者句柄等(直接引用)【找到具体在内存中的位置】。 这个就是静态链接过程(在类加载期间完成)。 动态链接是在程序运行期间完成的将符号引用替换为直接引用 (比如某个普通方法的调用)。
  • 初始化:上面的步骤完事儿以后,这一步主要是对类的静态变量初始化为指定的值,执行静态代码块。 比如刚才第二步的 public static final int a = 12; ,第二步给static变量赋了默认值,这一步就该把12赋值给它了。 还有 static的 User public static User user = new User(); 实例化User。

说明:主类在运行过程中如果使用到其它类,会逐步加载这些类。jar包或war包里的类不是一次性全部加载的,是使用到时才加载。

类加载顺序示例:

============
public class TestDynamicLoad {
static {
System.out.println(“加载TestDynamicLoad类中的静态代码块”);
}
public static void main(String[] args) {
new A();
System.out.println(“执行main方法中的代码”);
B b = null;//B不会加载,除非这里执行 new B()
}
}
class A{
static {
System.out.println(“加载A类中的静态代码块”);
}
public A(){
System.out.println(“加载A类中的构造方法”);
}
}
class B{
static {
System.out.println(“加载B类中的静态代码块”);
}
public B(){
System.out.println(“加载B类中的构造方法”);
}
}

执行结果:

加载TestDynamicLoad类中的静态代码块

加载A类中的静态代码块

加载A类中的构造方法

执行main方法中的代码

类加载器

========

  • 引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等
  • 扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包
  • 应用程序类加载器:负责加载ClassPath路径下的类包,主要就是加载我们应用中自己写的那些类
  • 自定义加载器:负责加载用户自定义路径下的类包

类加载器示例:

import com.sun.crypto.provider.DESKeyFactory;
import sun.misc.Launcher;
import java.net.URL;
public class TestJDKClassLoader {
public static void main(String[] args) {
System.out.println(String.class.getClassLoader());
System.out.println(DESKeyFactory.class.getClassLoader().getClass().getName());
System.out.println(TestJDKClassLoader.class.getClassLoader().getClass().getName());
System.out.println();
ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();
ClassLoader extClassloader = appClassLoader.getParent();
ClassLoader bootstrapLoader = extClassloader.getParent();
System.out.println("the bootstrapLoader : " + bootstrapLoader);
System.out.println("the extClassloader : " + extClassloader);
System.out.println("the appClassLoader : " + appClassLoader);
System.out.println(“AppClassLoader的父类加载器为ExtClassLoader,ExtClassLoader的父类加载器为null,null并不代表ExtClassLoader没有父类加载器,而是 BootstrapClassLoader”);
System.out.println();
System.out.println(“JRE的lib目录下的核心类库,bootstrapLoader加载以下文件:”);
URL[] urls = Launcher.getBootstrapClassPath().getURLs();
for (int i = 0; i < urls.length; i++) {
System.out.println(urls[i]);
}
System.out.println();
System.out.println(“JRE的lib目录下的ext扩展目录中的JAR类包,extClassloader加载以下文件:”);
String[] extClassloaderStr = System.getProperty(“java.ext.dirs”).split(“;”);
for (String s : extClassloaderStr) {
System.out.println(s);
}
System.out.println();
System.out.println(“加载ClassPath路径下的类包,appClassLoader加载以下文件:”);
String[] split = System.getProperty(“java.class.path”).split(“;”);
for (String s : split) {
System.out.println(s);
}
}
}
执行结果:
null
sun.misc.Launcher$ExtClassLoader
sun.misc.Launcher$AppClassLoader
the bootstrapLoader : null
the extClassloader : sun.misc.Launcher$ExtClassLoader@3dd3bcd
the appClassLoader : sun.misc.Launcher$AppClassLoader@14dad5dc
AppClassLoader的父类加载器为ExtClassLoader,ExtClassLoader的父类加载器为null,null并不代表ExtClassLoader没有父类加载器,而是 BootstrapClassLoader
JRE的lib目录下的核心类库,bootstrapLoader加载以下文件:
file:/D:/Environment/JDK/lib/resources.jar
file:/D:/Environment/JDK/lib/rt.jar
file:/D:/Environment/JDK/lib/sunrsasign.jar
file:/D:/Environment/JDK/lib/jsse.jar
file:/D:/Environment/JDK/lib/jce.jar
file:/D:/Environment/JDK/lib/charsets.jar
file:/D:/Environment/JDK/lib/jfr.jar
file:/D:/Environment/JDK/classes
JRE的lib目录下的ext扩展目录中的JAR类包,extClassloader加载以下文件:
D:\Environment\JDK\lib\ext
C:\Windows\Sun\Java\lib\ext
加载ClassPath路径下的类包,appClassLoader加载以下文件:
D:\Environment\JDK\jre\lib\charsets.jar
D:\Environment\JDK\jre\lib\deploy.jar
D:\Environment\JDK\jre\lib\ext\access-bridge-64.jar
D:\Environment\JDK\jre\lib\ext\cldrdata.jar
D:\Environment\JDK\jre\lib\ext\dnsns.jar
D:\Environment\JDK\jre\lib\ext\jaccess.jar
D:\Environment\JDK\jre\lib\ext\jfxrt.jar
D:\Environment\JDK\jre\lib\ext\localedata.jar
D:\Environment\JDK\jre\lib\ext\nashorn.jar
D:\Environment\JDK\jre\lib\ext\sunec.jar
D:\Environment\JDK\jre\lib\ext\sunjce_provider.jar
D:\Environment\JDK\jre\lib\ext\sunmscapi.jar
D:\Environment\JDK\jre\lib\ext\sunpkcs11.jar
D:\Environment\JDK\jre\lib\ext\zipfs.jar
D:\Environment\JDK\jre\lib\javaws.jar
D:\Environment\JDK\jre\lib\jce.jar
D:\Environment\JDK\jre\lib\jfr.jar
D:\Environment\JDK\jre\lib\jfxswt.jar
D:\Environment\JDK\jre\lib\jsse.jar
D:\Environment\JDK\jre\lib\management-agent.jar
D:\Environment\JDK\jre\lib\plugin.jar
D:\Environment\JDK\jre\lib\resources.jar
D:\Environment\JDK\jre\lib\rt.jar
D:\Project\Personal\website\reception\target\classes
D:\Environment\RepMaven\org\springframework\boot\spring-boot-starter\2.2.6.RELEASE\spring-boot-starter-2.2.6.RELEASE.jar
D:\Environment\RepMaven\org\springframework\boot\spring-boot\2.2.6.RELEASE\spring-boot-2.2.6.RELEASE.jar


相关文章
|
4月前
|
XML 监控 网络协议
云深处绝影四足机器人协议学习解析
本文详细介绍并解析了云深处绝影X20四足机器人的通信协议,包括TCP服务端端口号、基于Service的请求/响应通信机制、通信帧结构、消息类型、常见的通信示例如获取状态和导航请求,以及运动控制的参数和命令。文中还提出了对协议中某些未明确说明或可能存在的问题的疑惑。
48 0
云深处绝影四足机器人协议学习解析
|
4月前
|
安全 Java 数据库连接
后端框架的学习----mybatis框架(3、配置解析)
这篇文章详细介绍了MyBatis框架的核心配置文件解析,包括环境配置、属性配置、类型别名设置、映射器注册以及SqlSessionFactory和SqlSession的生命周期和作用域管理。
后端框架的学习----mybatis框架(3、配置解析)
|
4月前
|
人工智能 算法
AI 0基础学习,数学名词解析
AI 0基础学习,数学名词解析
28 2
|
5月前
|
网络协议 程序员 定位技术
学习网络的第一步:全面解析OSI与TCP/IP模型
**网络基础知识概览:** 探索网络通信的关键模型——OSI七层模型和TCP/IP五层模型。OSI模型(物理、数据链路、网络、传输、会话、表示、应用层)提供理论框架,而TCP/IP模型(物理、数据链路、网络、传输、应用层)更为实际,合并了会话、表示和应用层。两者帮助理解数据在网络中的传输过程,为网络设计和管理提供理论支持。了解这些模型,如同在复杂的网络世界中持有了地图。
103 2
|
6月前
|
SQL 缓存 算法
【源码解析】Pandas PandasObject类详解的学习与实践
【源码解析】Pandas PandasObject类详解的学习与实践
|
6月前
|
存储 前端开发 Java
深入解析Java类加载机制:原理、过程与实践
深入解析Java类加载机制:原理、过程与实践
219 2
|
6月前
|
存储 编译器 程序员
【C++高阶】C++继承学习手册:全面解析继承的各个方面
【C++高阶】C++继承学习手册:全面解析继承的各个方面
58 1
|
6月前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
48 1
|
6月前
数据结构学习记录——堆的删除(思路图解、代码实现、逐段解析)
数据结构学习记录——堆的删除(思路图解、代码实现、逐段解析)
69 1

推荐镜像

更多