JVM结构之类加载
1.java代码编译到字节码过程
首先分析此法和语法的正确性,再对代码进行编译,编译为字节码(.class结尾的文件)
2.类加载子系统作用
类加载子系统负责从文件或者网络中加载class文件,class有特定的标识(字节码文件都以CA FE BA BE 标识开头)
1.由classLoader负责class文件的加载
2.由ExecutionEngine负责看他是否可运行
3.加载类的信息存放在方法区(元数据区)
4.方法区存放运行时常量池,存常量静态变量
3.classLoader作用
1.class文件处于硬盘之中,classLoader将其加载至JVM中
2.在JVM中的class文件被称为元数据模板,存于方法区中
3.创建实例
4.类加载过程
1.加载
1.通过类地址获得类的二进制字节流
2.将这个字节流所代表的静态存储结构转换为方法区运行时结构
3.在内存中生成一个代表这个类的Class类,作为方法区这个类的访问入口
2.链接
1.验证:检验加载的类是否有正确的内部结构,并于其他类协调一致
2.准备:给类分配内存,设置默认的初始值
3.解析:将类中的引用换为直接引用(把枚举值换成真正的值,因为枚举类不一定加载)
3.初始化
类何时初始化?
1.new对象
2.Class.forName(“类地址”)
3.初始化子类
4.调用类的静态方法给静态变量赋值
4.类初始化顺序
1.加载父类的静态块、静态变量(顺序)
2.加载子类的静态块、静态变量(顺序)
3.加载父类代码块和常量
4.父类构造方法
5.加载子类代码块和常量
6.子类构造方法
5.类的加载器分类
JVM中支持两种类型的类加载器,分别为引导类加载器和自定义类加载器。(扩展类加载器和应用程序类加载器属于自定义类加载器),判断是否为自定义类加载器的原理是是否派生于ClassLoader的类加载器
1.引导类加载器(启动类加载器)
主要由c/c++开发,嵌套在JVM内部,加载核心类库,不集成于ClassLoader,没有付加载器,
负责加载扩展类加载器和应用程序类加载器并为他们指定父类加载器。
引用类加载器包名为 java、javax、sun开头
2.扩展类加载器
由java编写,由sun.misc.launcher$ExtClassLoader实现派生于ClassLoader
上层为引导类加载器
从 java.ext.dirs 系统属性所指定的目录中加载类库,或从 JDK 系统安装目录的 jre/lib/ext 子目录(扩展目录)下加载类库.如果用 户创建的 jar 放在此目录下,也 会自动由扩展类加载器加载。
3.应用程序类加载器
Java 语言编写的,由 sun.misc.Launcher$AppClassLoader 实现. 派生于 ClassLoader 类. 上层类加载器为扩展类加载器. 加载我们自己定义的类. 该类加载器是程序中默认的类加载
上层为扩展类加载器
可以通过 **类名.getClassLoader().ClassLoader.getSystemClassLoader()**获得
6.双亲委派机制
为了防止用户自己定义的类干扰到Java的核心类所设置的一种类加载机制。# 系列
原理:
1.类加载器收到类加载的请求,并不会自己直接加载,把这个类委托给父类加载器
2.父类加载器也重复向上委托给父类加载器直至顶端启动类加载器。
3.类加载器可以如可以完成,则结束,不可以完成
4.向下委托给子类加载器,重复,直至子类加载器加载了就结束
5.如若加载器均不能加载,则抛出ClassNotFoundException异常
这个机制后如果我们在自己建一个java.lang.String加载这个类,则会向上委托,直至启动类加载器启动类加载器直接加载,类加载结束(没有用到我们自己建立java.lang.String类)防止核心库被污染
7.沙箱安全机制
沙箱主要限制系统资源访问,例如:CPU、内存、文件系统、网络。不同级别的啥想对这些资源访问的限制也可以不一样
8.类的主被动使用
1.主动使用:
1.new出来的对象
2.调用类的静态方法
3.反射
4.访问类的静态变量
5.执行该类的main方法
6.初始化该类的子类
2.被动使用:
1.调用类的静态常量
2.调用该类的数组
注意:
调用的静态常量不能经过计算例如:
public final static a=new Random().nextInt() 为主动使用