2. 类加载器子系统
abstract
本文主要介绍类加载子系统,其中包括类的加载过程:加载、链接、初始化;以及 ClassLoader 的分类和 ClassLoader 的双亲委派机制等内容。
2.1. 内存结构
简图
详细图
笔记(Class Loader SubSystem)
类的加载分为3个环节:Loading -> Linking -> Initialization
加载需要用到类加载器,类加载器分为3种
BootStrap ClassLoader
:引导类加载器Extension ClassLoader
:扩展类加载器Application ClassLoader
:应用程序类加载器
笔记(Runtime Data Area)
PC寄存器(PC Register):每个线程一份,所以放了很多份
虚拟机栈(Stack Area):每个线程一份,每个线程的栈里一个一个的解构称为栈帧。还有一些细节的内部结构后续对应的章节会详细讲解。
Stack Area
- LV - Local Variables 本地变量表
- OS - Operation Stack 操作数栈
- DL - Dynamic Linking 动态链接
- RA - Return Address 返回地址
堆区(Heap Area):主要是创建JAVA对象的,这些对象,我们主体都分配在这个堆空间当中,也是我们内存当中算是最大的一块空间,也是GC,重点要考虑的一块空间。堆区是共享的,被多个线程所共享的。
方法区(Method Area):主要是来存放我们的一些类的信息、一些常量、一些域信息、方法信息等等。方法区,只有HotSpot虚拟机才有,像JRockit和J9他们其实都没有。
如果自己想手写一个Java虚拟机的话,主要考虑哪些结构呢?
- 类加载器
- 执行引擎
2.2 类加载器与类的加载过程
2.2.1 类加载器子系统作用
- 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识CAFA BABE(0xCAFEBABE)。
- ClassLoader 只负责Class文件的加载,至于它是否可以运行,则有 Execution Engine决定。
- 加载的类信息存放在一块称为方法区(Method
Area)的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)。
笔记
字节码文件是物理磁盘上的一个文件,类加载器主要负责把这个文件加载到内存中,然后生成大的class的一个实例。
字节码结构中的常量池(constant pool),在运行的时候加载到内容中,就称为运行时常量池。
《Java虚拟机原理图解》 1.1、class文件基本组织结构 这篇文章对于类的字节码结构有更深入的讲解,第二部分也会深入讲解。此处了解即可。
2.2.2 类加载器ClasLoader角色
- class file 存在本地硬盘上,可以理解为设计师在纸上的模板,而最终这个模板在执行的时候是要加载到JVM当中来根据这个文件实例化出n个一模一样的实例。
- class file 加载到JVM中,被称为DNA元数据模板,放在方法区(Method Area)。
- 在.class 文件 JVM 最终成为元数据模板,此过程就要一个运输工具(类加载器 Class Loader),扮演一个快递员的角色。
2.2.3 类的加载过程
/**
*示例代码
*/
public class HelloLoader {
public static void main(String[] args) {
System.out.println("谢谢ClassLoader加载我...");
System.out.println("你的大恩大德,我下辈子再报!");
}
}
加载(Loading)
注意
我们这里提到的类的加载过程是一个宏观上的概念,然后它分成三个环节。三个环节中的第一个环节,恰好也称为叫加载,这个加载呢是狭义上的。而类的加载过程中的加载是广义上的加载。
第一步的