JVM组成
- 类加载系统:负责完成类的加载,将字节码文件加载进内存(方法区)
- 运行时数据区:在运行java程序时产生的数据会保存在运行时数据区
- 执行引擎:执行具体的指令(代码)
一个类被加载进JVM要经历那几个过程? - 加载:通过io流的方式把字节码文件读取到jvm(方法区)中
- 校验:通过校验字节码文件的头四位的16进制是否是cafebabe
- 准备:为类中的静态部分开辟空间并赋初始化值
- 解析:将符号引用转换成直接引用(将调用方法时的字符表现形式,转换成方法对应的地址)。——静态链接
- 初始化:为类中的静态部分赋指定值并执行静态代码块。
类被加载后,类中的类型信息、方法信息、属性信息、运行时常量池、类加载器的引用等信息会被加载到元空间(1.7之前称方法区,1.7改为永久代,1.8开始称元空间)中。
类加载器
类是谁来负责加载的?——类加载器
- Bootstrap ClassLoader 启动类加载器:负责加载jre/lib下的核心类库中的类,如rt.jar、charset.jar
- ExtClassLoader 扩展类加载器:负责加载jre/lib下的ext目录内的类
- AppClassLoader 应用类加载器:负责加载用户自己写的类
- 自定义加载器:自己定义的加载器,可以打破双亲委派机制。
类加载过程
AppClassLoader、ExtClassLoader、BootStrapClassLoader之间并不是子类与父类之间的关系。
- BootStrapClassLoader是调用本地方法获得(C++),如果打印该类实例对象返回为null。
- ClassLoader类中有一个final修饰的成员变量ClassLoader
public abstract class ClassLoader {
private static native void registerNatives();
static {
registerNatives();
}
// The parent class loader for delegation
// Note: VM hardcoded the offset of this field, thus all new fields
// must be added *after* it.
private final ClassLoader parent;
也就是说BootStrapClassLoader将其自身作为参数传递给了ExtClassLoader的构造函数,ExtClassLoader将其作为参数传递给了AppClassLoader的构造函数,是组合的关系。注:双亲委派机制及如何打破双亲委派机制,将在下篇文章中具体解释。