JVM的私房笔记(一)类加载机制与类加载器 by 葵鱼
前言
准备写这份笔记的时候,想法还是较为简单的,就是希望能将学到的,听到的,查到的,看到的东西做一个总结,以免后面自己遗忘。同时我将会以段落和副标题的形式编写。有什么问题或者错误的地方,还请大家多指正,希望你能获得你想要的知识,或者指出我错误的地方,在巩固自己的同时帮助我更好的提升。感谢各位,同时也希望大家能多多转发,嘿嘿嘿。
-.-.-.-.-.-.-.-.-.-.-.-.-.–.-.–.-.-.–.-.–.-.-.–.-.-.–.-.-.-.-.-.-.-.-.-.–.-.-.-.-.-.-.-.-.-.-.-
快速跳转:
JVM的私房笔记(一)类加载机制与类加载器 by 葵鱼
JVM的私房笔记(二)JAVA 内存模型 by 葵鱼
JVM的私房笔记(三)垃圾收集与垃圾收集器 by 葵鱼
-.-.-.-.-.-.-.-.-.-.-.-.-.–.-.–.-.-.–.-.–.-.-.–.-.-.–.-.-.-.-.-.-.-.-.-.–.-.-.-.-.-.-.-.-.-.-.-
JAVA类加载过程
1、通过C++实现代码,调用windows下的java.exe,调用jvm.dll,创建java虚拟机
2、创建一个引导类加载器实例(c++实现)
3、C++调用java代码,创建 JVM启动器实例,sun.mis.cLauncher,该类由类加载器负责加载,创建其他类加载器(JVM有很多类加载器)
4、sun.misc.Launcher.getLauncher(),获取运行类自己的加载器ClassLoader,是AppClassLoader的实例。
5、launcher.getClassLoader(),调用loadClass加载要运行的类Math。
6、运行用户类代码
7、JVM销毁。
类加载过程
加载、验证、准备、解析、初始化。
1、加载:将字节码文件放入内存。
2、验证:cafe babe 标准字节码开头文件。在类加载时,会先验证一下字节码的规范。
3、准备:会把静态变量初始赋值(int 为0 boolean为false),这个初始值是jvm规定的,并不会改变。(如果加了final,则变为常量,直接赋值入虚拟机)
4、解析:将符号引用替换为直接引用。(符号,例如类名,方法名等等。将这些符号替换内存指针或者句柄),这就是所谓的静态链接(动态链接是在程序运行期间将符号引用替换为直接引用。)
5、 初始化:把静态变量初始化为对应的值(初始化之前,静态变量都是默认值)类被加载到方法区中后,主要包含***运行时常量池,类型信息,字段信息,方法信息,类加载器的引用,对应class实例的引用***等等。
JVM的类加载机制,其实是一种懒加载
类加载器和双亲委派
引导类加载器:位于JDK lib目录下,由C++编写,用于加载支撑JVM运行的rt.jar(java.nio,java.time,java.util等工具类,都在rt.jar中) charsets.jar等类)
扩展类加载器:负责加载支撑JVM运行的,位于JRE exrt目录下的jar包
应用程序加载器:负责加载ClassPath路径下的类,主要是加载你自己写的那些类。
自定义加载器:负责加在用户自定义路径下的类
所有类加载器,都继承与ClassLoader类,没个类加载器都有一个参数parent,标定了类加载器的父亲(与双亲委派有关,但并不是父类)。
<------------------------------------------------------------------------------------------------------->
Launcher类初始化过程(参考上图的类加载过程):获取ExtClassLoader(父类为URLClassLoader),AppClassLoader(传入ExtClassLoader作为参数,父类也为URLClassLoader,但其parent,为传入的ExtClassLoader)。
引导类加载器通过C++代码加载,然后引导类加载器加载ExtClassLoader与AppClassLoader,同时构造两个类加载器的父级关系(通过parent属性)
ExtClassLoader的parent是BootStrapLoader是null,因为引导类加载器是通过C++加载进来的,并不存在JVM中
备注:上面这一部分我自己也理解的不是很清楚,等待大佬指正。
<----------------------------------------------------------------------------------------------------------->
双亲委派机制:
在没有自定义加载器的时候,一个类会先请求应用程序加载器AppClassLoader加载,
AppClassLoader扫描自己已经加载的类,如果有则返回,若没有,则委托parent加载,AppClassLoader委托ExtClassLoader。ExtClassLoader进行相同的操作,若不在自己的已加载列表中,则委托parent,引导类加载器 BootStrapClassLoader。BootStrapClassLoader发现这个类不在自己已加载列表里,会尝试从JDK,lib文件夹中加寻找这个类加载(引导类加载器只负责加载JDK lib文件夹下的加载器)。若没有,则向下委派扩展类加载器去加载。扩展类加载器扫描ext文件夹,若无则委托AppClassLoader。AppClassLoader会扫描target目录下(如果是IDEA的话),则必然找到,加载(调用LoadClassPath()方法)。
问题:为什么要从AppClassLoader开始先向上委托?
对于一个web项目来说,95%以上的类,都是由AppClassLoader进行加载的,而且很多类会重复加载非常多次。如果每次都从引导类开始向下委派,无疑效率很低。直接请求AppClassLoader,若存在则返回,会大大提高效率。仅仅类第一次加载的时候效率会较低而已。
为什么要设计双亲委派机制?
1、沙箱安全机制:避免底层API类被修改,影响安全性。
例如: 我们构建一个类叫java.lang.String.class,这个类与JDK的String同名。在加载这个类的时候,会先向上委托到BootStrapClassLoader,返回java本身的API类String,并不会加载你实际写的这个类。保证了java.lang.String只会加载JDK的API类而非同名自定义类。防止核心API库被修改。
2、避免类的重复加载:当父加载器已经加载过某个类,例如ExtClassLoader已经家在过这个类了,那么会直接返回这个类,不会让AppClassLoader再加载一次。
打破双亲委派机制
由于双亲委派机制是通过java.lang.ClassLoader的 LoaderClass函数完成的,打破双亲委派,就重写这个函数就可以了。
Tips:可能会遇到,比如所有类都继承于Object,如果所有类都打破双亲委派,用自定义加载器记载,会出现Object类加载不到的情况。所以要将API类的加载过滤掉,API类依旧遵循双亲委派,自己实现的类打破双亲委派。
例子:
Tomcat上的每个war包,都会有一个对应的WebappClassLoader(他不是生成了一个新的ClassLoader类,是通过类,new了一个webClassLoader对象,通过这个对象加载类。),保证了项目之间的类的隔离(JVM区分相同类,除了包名、类名,还要看加载器是否 相同)。项目自己的类,自己用WebappClassLoader,项目中引用的tomcat公用类,还是委托上级加载。
JVM的私房笔记(一)类加载机制与类加载器 by 葵鱼相关推荐
- jvm类加载机制和类加载器_在JVM之下–类加载器
jvm类加载机制和类加载器 在许多开发人员中,类加载器是Java语言的底层,并且经常被忽略. 在ZeroTurnaround上 ,我们的开发人员必须生活,呼吸,饮食,喝酒,并且几乎与类加载器保持亲密关 ...
- java赋值语句_深度分析:面试阿里,字节99%会被问到Java类加载机制和类加载器...
1. 类加载机制 所谓类加载机制就是JVM虚拟机把Class文件加载到内存,并对数据进行校验,转换解析和初始化,形成虚拟机可以直接使用的Jav类型,即Java.lang.Class. 2. 类加载的过 ...
- JVM:类加载机制之类加载过程
类加载机制概念 Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.准备.解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制.* Class文件由 ...
- jvm类加载机制_JVM 类加载机制
学习导图 一.为什么要学习类加载机制? 今天想跟大家唠嗑唠嗑 Java 的类加载机制,这是 Java 的一个很重要的创新点,曾经也是 Java 流行的重要原因之一. Oracle 当初引入这个机制是为 ...
- 深入理解Java虚拟机——JVM类加载机制(类加载过程和类加载器)
一.什么是类加载机制? 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 二.类加载的时机 类 ...
- java中类加载机制、类加载过程和类加载器层次
1.类加载机制 jvm把class文件加载到内存,并对数据进行校验.解析和初始化,最终形成jvm可以直接使用的java类型的过程. (1)加载 将class文件字节码内容加载到内存中,并将这些静态数据 ...
- 29.类加载机制、类加载过程、加载、验证、准备、解析、初始化、总结
29.类加载机制 29.1.类加载过程 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.它们开始的顺序如下图所示: 其中类加载 ...
- java类加载机制、类加载器、自定义类加载器
类加载机制 java类从被加载到JVM到卸载出JVM,整个生命周期包括:加载(Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化( ...
- JVM:类加载机制之类加载器
JVM设计者把类加载阶段中的"通过'类全名'来获取定义此类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称 ...
最新文章
- Oracle分析函数详述
- 四色着色问题 c语言编程,数据结构-图着色问题
- Python之eval函数实例解释
- 企业管理软件 Compiere ERPCRM
- PAT 甲级 1004
- JS设计模式初识(四)-迭代器模式
- linux下phpmyadmin安装
- B. Forgery
- 【Notification】屏蔽特定应用的通知提示
- MAC设置JDK环境变量
- input type=file 选取文件路径时出现fakepath问题IE浏览器解决办法
- SQLMAP使用教程(一)
- html实现让电脑断网的功能,简单几步,即可实现电脑自动断网
- Emerging Properties in Self-Supervised Vision Transformers(2021)
- 寒江独钓前辈的第一个例子的编译运行过程
- 接入支付宝电脑网站支付实现JAVA版
- Adobe 安装程序无法初始化,请下载Adobe Support Advisor检测该问题
- 现代企业管理——【ERP管理】
- 2021年中国光纤传感器市场趋势报告、技术动态创新及2027年市场预测
- Android Web应用高级编程