JVM JDK JRE三者关系
JDK = JRE + 一众工具
JRE = JVM + 一众lib jar
JVM 为什么是跨平台的
- 由于它编译出字节码文件 class
- 每种平台都有对应的JVM 可以对class 文件加载解释生成机器运行指令
类加载入JVM 过程
1.加载;通过IO流的方式把字节码文件读入到JVM中的方法区
2.校验:通过校验字节码文件内容的头4位16进制是否是java 魔数café babe
3 准备:为类中静态部分开辟空间并赋初始值
4 解析 :将符号引用转成直接引用(静态链接)
5 初始化: 为类中的静态部分指定值并执行静态代码块
类被加载后,类中的类型信息,方法信息,属性信息,运行时常量池,类加载的引用等信息会被加载到元空间中
双亲委派
JVM 类加载器有BootStrapClassLoader, ExtClassLoader, AppClassLoader
前者为后者的父类加载器
BootStrapClassLoader (C++ 编写) :加载 /jre/lib
Launcher.ExtClassLoader (DCL):加载 /jre/lib/ext
Launcher.AppClassLoader (参数paraent =ExtClassLoader ):加载classpath
工作过程,首先底层AppClassLoader 去查看类是否被加载否,没被加载就找上一级父类加载器ExtClassLoader ,调用父类的classLoad() 方法,其实这个过程就是查看缓存中是否有被加载过,如果没有继续调用BootStrapClassLoader 的classLoad() ,没如果还没有,那就查自己加载的路径是否存可以加载在这个class 。如果没有,就找下一级ExtClassLoader 去加载是否有,如果没有再找AppClassLoader 去加载。如果还是没有就报错了NotClassFoundException
1.如何定义自己的classLoader: 继承classLoader,AppClassLoader 成为父类加载器(即是内部parent 变量), 和重写findClass 方法
2.如何打破双亲委派机制: 继承classLoader, 和重写findClass 和 loadClass方法
3. 为什么有双亲委派这个机制,主要是为了防止核心类被随意篡改,例如String 不被篡改。防止类被重复加载