JVM的区域划分:
JVM的内存区域划分分为:堆,方法区,栈,程序计数器这四个部分组成。
堆:堆就是用来存储我们new出来的对象。
方法区:方法区用来存储我们的类对象。
类对象中有啥?
1.包含这个类的各种属性的名字、类型、访问权限
2.包含了这个类的各种方法的名字,参数类型,返回值类型
3.包含了这个类的static成员
栈:栈是用来存储我们的局部变量。
程序计数器:程序计数器用来存放我们的内存地址,这个内存地址就是接下来要执行指令的地址。
类加载过程:
类加载是JVM中一个非常核心的流程,做的事情就是把.class文件转换成JVM的类对象。
类加载的基本流程分为:1.加载 2.验证 3.准备 4.解析 5.初始化
加载:在我们进行类加载的时候,代码中需要加载这个类,我们就需要先找到.class文件,这个.class文件在特定的目录下,我们这时候就需要到指定目录读取这个.class文件然后把里面的数据读入内存中。
验证:我们需要对加载的.class文件进行验证,看这个文件是否合法的.class文件,除了验证文件格式还会验证文件的字节码。
准备:其实就是为了类对象中的一些成员分配内存空间(静态变量),然后进行一个初步的初始化操作的一个事情。
解析:解析这个步骤针对的是我们的字符串常量池进行处理,我们的程序不是一启动就加载所有的类都加载,而是需要哪个类才加载哪个类。
初始化:对真正的静态变量进行初始化操作,然后执行静态代码块。
双亲委派模型:双亲委派模型就类加载中的一个不起眼的小步骤。JVM中有三个类加载器,分别为BootStrap、ExClassLoader、AppClassLoader。每个类加载器都负责加载一个范围的类。
在我们要加载某个类的时候,会先到AppClassLoader中,但是不进行扫描,而是交给它的父亲也就是ExClassLoader,ExClassLoader也不直接进行扫描,而是再找到它的父亲,BootStrap,BootStrap也不进行直接扫描,而是寻找它的父亲,发现它的父亲不存在,那只能进行扫描操作,如果遇到需要扫描的类不在自己这里,则会交给自己的孩子ExClassLoader进行扫描,ExClassLoader中扫描不到,就会交给AppClassLoader进行扫描,如果还是扫描不到就会抛出一个异常,告诉我们该类找不到。这就是双亲委派模型。一开始不直接扫描而是寻找自己的父亲,直到达到最顶层,之后开始扫描操作,如果没扫描到需要的类则交给自己的孩子去做。这个流程非常像父亲叫孩子做事情,所以叫做双亲委派模型。
双亲委派模型虽然有其优点,但在某些情况下也存在一定的问题,所以我们有时候需要打破双亲委派模型。
双亲委派模型的优点是:1.避免重复加载同一个类 2.使用双亲委派模型可以避免Java的核心API不会被篡改。