当前位置:网站首页>JVM(3) 类加载
JVM(3) 类加载
2022-06-29 19:16:00 【Demon_bh】
类加载
1、类加载阶段
1) 加载
- 将类的字节码载入方法区(元空间jdk1.8),内部采用C++
- 有父类先加载父类
- 反射是通过对象头class地址找到元空间中Class类对象,从中获取_fields, _methods等信息!
2) 连接
1、验证:字节码是否符合规范
2、准备:给类static变量分配空间,确认默认值==(static int a = 10)==
- static 变量确认默认值和赋值是两个步骤,确认默认值在准备阶段完成a值为0,赋值在初始化阶段完成a值为10
- 但如果 static 变量 是 final 的基本类型,以及字符串常量,那么赋值在准备阶段完成
- 如果 static 变量是 final 的,但属于引用类型,那么赋值也会在初始化阶段完成将常量池中的符号引用解析为直接引用
3、解析:将常量池中的符号引用解析为直接引用(确定引用类的地址)
3) 初始化
初始化即调用 () 方法 ,该方法包含类中所有静态变量的赋值与所有静态代码块执行,虚拟机会保证这个类的『构造方法』的线程安全。
*类初始化是【懒惰的】:
- main 方法所在的类,总会被首先初始化
- 首次访问这个类的静态变量或静态方法时
- 子类初始化,如果父类还没初始化,会引发
- 子类访问父类的静态变量,只会触发父类的初始化
- Class.forName
- new 会导致初始化
不会导致类初始化的情况:
- 访问类的 static final 静态常量(基本类型和字符串)不会触发初始化(连接阶段)
- 类对象.class 不会触发初始化(加载阶段)
- 创建该类的数组不会触发初始化
*利用类加载初始化特性实现懒汉单例模式
public class Singleton {
//私有构造器,不能被外部调用
private Singleton() {
}
// 内部类中保存单例
private static class LazyHolder {
static final Singleton INSTANCE = new Singleton();
}
// 第一次调用 getInstance 方法,才会导致内部类加载和初始化其静态成员
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
特点:
- 懒惰实例化
- 初始化时的线程安全是由类加载器保障的
2、类加载器
- Bootstrap ClassLoader jre/lib (C++编写,无法直接访问)
- Extension ClassLoader jre/lib/ext
- Application ClassLoader classpath (系统类加载器)
- 自定义类加载器 自定义
特点:
- 每个类加载器都有一个独立的类命名空间
- 任意一个类,都需要类本身+加载此类的类加载器共同确定唯一性
**双亲委派模式
工作过程:一个类加载器收到了加载类的请求,他首先把这个请求委派给上级类加载器去完成,每层都是如此,直到传递给顶层的启动类加载器,只有当上层类加载器无法完成加载请求(搜索范围中没有这个类)时,下层加载器才会尝试自己加载。
优点:
- 如Object类,他的位置只能被最顶层的启动类加载器加载,所以无论哪个类加载器要加载这个类,最终都是由启动类加载器加载,这保证了Object类在各种类加载器环境中的都是同一个。
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先查找该类是否已经被该类加载器加载过了
Class<?> c = findLoadedClass(name);
// 如果没有被加载过
if (c == null) {
long t0 = System.nanoTime();
try {
// 看是否被它的上级加载器加载过了 Extension 的上级是Bootstarp,但它显示为null
if (parent != null) {
c = parent.loadClass(name, false);
} else {
// 看是否被启动类加载器加载过
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
//捕获异常,但不做任何处理
}
if (c == null) {
// 如果还是没有找到,先让拓展类加载器调用 findClass 方法去找到该类,如果还是没找到,就抛出异常
// 然后让应用类加载器去找 classpath 下找该类
long t1 = System.nanoTime();
c = findClass(name);
// 记录时间
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
==在加载JDBC数据库驱动时,使用的是应用程序类加载器(没使用启动类加载器,打破了双亲委派模式)
边栏推荐
- After CDN is added to the website, the Font Icon reports an error access control allow origin
- Point, line, surface and body of enterprise digital transformation!
- isalpha()方法介绍
- Win11策略服务被禁用怎么办?Win11策略服务被禁用的解决方法
- 网站加了CDN后,字体图标报错Access-Control-Allow-Origin
- 76.二叉树的最近公共祖先
- 75. nearest common ancestor of binary search tree
- Various API methods of selenium
- 逻辑结构与物理结构
- KDD 2022 | 协同过滤中考虑表征对齐和均匀性
猜你喜欢
随机推荐
Lingyun going to sea | Wenhua online &huawei cloud: creating a new solution for smart teaching in Africa
【历史上的今天】6 月 29 日:SGI 和 MIPS 合并;微软收购 PowerPoint 开发商;新闻集团出售 Myspace
QC protocol + Huawei fcp+ Samsung AFC fast charging 5v9v chip fs2601 application
Win11系统小组件打不开?Win11系统小组件无法打开解决方法
虎符限币种提现 用户曲线出金即亏损
销量赶不上拿钱速度,威马赴港救急
76.二叉树的最近公共祖先
MBA-day26 数的概念与性质
3-3主機發現-四層發現
SQL Server Backup and restore command operations
QC协议+华为FCP+三星AFC快充取电5V9V芯片FS2601应用
php实现 提取不重复的整数(编程题目能够最快的熟悉函数)
炒股用同花顺开户交易安全吗?
领先11%,华为云天筹AI求解器再度登顶国际权威榜单
暴力解决《猜名次》问题
数据库是什么?数据库详细笔记!带你走进数据库~你想知道的这里都有!
swift可选值总结
ArrayList&lt; Integer&gt; Use = = to compare whether the values are equal, and -129=- 129 situation thinking
Third party tools and framework integration
创作者基金会 6 月份亮点









