1.JVM中内存区域划分
JVM中的内存主要被划分为4部分区域,分为程序计数器、元数据区、栈和堆

1.1程序计数器
程序计数器主要是用来保存指令执行到哪一个地址
1.2元数据区
元数据区主要是保存当前类加载好的一些数据,比如类名是什么,有哪些属性,属性名是什么,继承了哪个类,实现了哪些接口,接口的名字是什么,接口的参数列表,有哪些字符串常量,哪些静态属性等等信息
1.3栈
Java中的栈主要是保存了一些Java方法间的调用关系,如下图

1.4堆
堆主要是用来保存new出来的对象,也是JVM中区域最大的一块。
举个例子:Test t = new Test()
new Test()的这部分申请的空间一定是存储在堆中的,但是变量t不一定是存储在堆中的,此时会分为3种情况
第一种情况:如果t是一个局部变量,那么t就是存储在栈中
第二种情况:如果t是一个成员变量,那么t就是存储在栈中
第三种情况:如果t是一个静态变量,那么t就是存储在元数据区中
2.类加载机制
2.1类加载的步骤
首先就是根据类的全限定名找到对应的.class文件,打开并读取.class文件的内容到内存中,接着就是对读取到的.class里面的内容进行校验,判断.class里面的内容是否合法,并且将这部分内容转换成结构化的数据,在接着就是给类对象申请内存空间,这里申请的空间相当于是一部分全0的空间,然后就是针对字符串常量进行初始化,也就是将从.class文件中解析到的字符串常量保存到内存中,最后一步就是进行初始化,最后一步主要是针对类的各种属性进行初始化,包括类中的成员变量,如果这个类还有父类并且父类没有加载,此时也会触发父类的类加载
2.2双亲委派模型
谈到双亲委派模型,就要知道类加载器,类加载器是JVM中专门负责类加载的模块,且在JVM中提供了3个默认的类加载器,分别为BootstrapClassLoader、ExtensionClassLoader和ApplicationClassLoader,且在ApplicationClassLoader中有一个parent引用指向ExtensionClassLoader,ExtensionClassLoader也有一个parent引用指向BootstrapClassLoader,BootstrapClassLoader中也有一个parent引用,但是BootstrapClassLoader的引用是执行null的
这3个类加载的主要任务就是根据全限定类名找.class文件,且这三个类加载器的寻找范围不同。
BootstrapClassLoader的寻找范围是Java的标准库的目录,ExtensionClassLoader的寻找范围是Java的扩展库的目录,ApplicationClassLoader的寻找范围是第三方库目录或者项目目录
接着就是委派的过程,我们知道类加载器的任务就是负责类加载,首先,ApplicationClassLoader会先作为入口首先接收到类加载的任务,但是此时ApplicationClassLoader此时并不会立即执行这个任务,而是将这个类加载的任务线委派给父亲ExtensionClassLoader,此时ExtensionClassLoader接收到类加载的任务,此时也不会立即执行这个类加载的任务,也是会将这个任务委派个父亲BootstrapClassLoader,此时BootstrapClassLoader接收到类加载的任务之后,由于BootstrapClassLoader的parent引用指向null,无法将类加载任务委派给其他的类加载器,此时BootstrapClassLoader根据全限定类名到Java的标准库目录中去寻找对应的.class文件,如果找到就加载,如果没找到,此时就会将类加载的任务还给ExtensionClassLoader,此时ExtensionClassLoader也会到Java的扩展库中去寻找.class文件,如果找到就加载,没找到的话也会将任务还给ApplicationClassLoader,此时ApplicationClassLoader就会到第三方库目录或者本地项目目录去寻找对应的.class文件,如果找到就加载,但是此时在找不到的话,就会抛异常