类加载器
负责从文件系统或者网络中加载class文件,class文件在文件开头有特定的文件标识,加载的类信息存放于一块称为方法区的内存空间,还会存放运行时的常量池信息
class file加载到jvm中,被称为dna元数据模板,放在方法区中 加载器扮演一个快递员角色
加载过程
加载
-
通过一个类的全限定名获取定义此类的二进制字节流
-
将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
-
在内存中生成一个代表这个类的java.lang.Class 对象,作为这个方法去这个类的各种数据的访问接口
链接 -
验证 verify 保证class文件中包含信息符合当前虚拟机要求,
四种验证:文件格式验证,元数据验证,字节码验证,符合引用验证 -
准备 prepare
为类变量分配内存并且设置该类变量的默认初始值,0值
不包含final修饰的static 因为final 在编译阶段就会分配内存,
这里不会为实例变量初始化,类变量会分配在方法区中,而实例变量会随 这对象一起分在java堆中 -
解析 resolve
将常量池的符号引用转化为直接引用
在jvm执行完初始化之后在执行
符号引用字面量形式定义在class文件格式中,
直接引用就是指向目标的指针、相对偏移量或一个间接定位到目标的指针
-
初始化阶段就是执行类构造器方法()的过程
此方法不需要定义,是javac编译器自动收集类中的**所有类变量的赋值动作和静态代码块中的语句合并**而来
构造方法中指令按语句在源文件中出席那的顺序执行
必须保证一个类的() 方法在多线程下被同步加锁
分类
- 引导类加载器(启动类加载器)Bootstrap classLoader
java核心类库 c++ rt.jar
没有父类加载器
加载 扩展类 、应用程序类加载器
2 . 自定义加载器
将所有派生于抽象类的CLassLoader的类加载
1. 扩展类加载器Ext
jre/lib/ext子目录
2. 应用程序类加载器 appClassLoader(系统类加载器)
加载环境变量 应用的类由它加载
隔离加载类
修改类加载的方式
扩展加载源
防止源码泄露
实现步骤
1. 继承 ClassLoader 重载loadClass
2. 加载findClass
3. 继承URLClassLoader
类加载器获取途径
双亲委派机制
请求交给父类处理
优势
避免类的重复加载
保护程序安全,防止核心Api被篡改
沙箱安全机制
保护核心api被攻击
类加载器引用
jvm必须知道 一个类型是由启动加载器加载的还是用户类加载器加载的,如果是用户类加载器加载的,jvm会将这个类加载器的一个引用作为类型信息的一部分保存在方法区中
对类的使用分为主动使用和被动使用
主动使用:
- 创建类的实例
- 访问某个类后接口的静态变量,或赋值
- 调用静态方法
- 反射
- 初始化一个类的子类
- java虚拟机启动时被表明为启动类
- jdk 7支持动态语言
其他为被动 不会导致初始化