目录
[2. 数组类的加载](#2. 数组类的加载)
[1. 验证阶段](#1. 验证阶段)
[2. 准备阶段](#2. 准备阶段)
[3. 解析阶段](#3. 解析阶段)
[1. static与final的搭配问题](#1. static与final的搭配问题)
[2. ()的线程安全性](#2. ()的线程安全性)
[3. 类对 的主动使用和被动使用](#3. 类对 的主动使用和被动使用)
一、概述
Java中基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载。
从class文件到加载到内存中的类,到类卸载出内存为止,它的声明周期包括如下的七个阶段:

二、Loading(加载)阶段
加载阶段,简而言之就是查找并加载类的二进制数据,生成Class的实例。

1.类模型和Class实例的位置
加载的类在JVM中创建相应的类结构,类结构会存储在方法区中。
类将.class文件加载到方法区(元空间)后,会在堆中创建一个Java.lang.Class对象,用来封装类位于方法区内的数据结构,该Class对象是在加载类的过程中创建的,每个类都对应有一个Class类型的对象。

2. 数组类的加载

三、Linking(链接)阶段
1. 验证阶段
这个阶段的目的是保证加载的字节码是合法、合理且符合规范的。

2. 准备阶段
这个阶段是为类的静态变量分配内存,并将其初始化为默认值。

注意:
- 这里不包含基本数据类型 的字段用static final修饰 的情况,因为final在编译的时候就会分配了,准备阶段 会显式赋值。非final修饰的变量,在该环节进行默认初始化赋值。
- 这里不会为实例变量初始化,类变量(静态变量)会分配在方法区中,实例变量(成员变量)会随着对象一起分配到Java堆中
- 这个阶段不会有代码的执行
3. 解析阶段
该阶段是将类、接口、字段和方法的符号引用转换为直接引用。

用大白话解释就是,我要去北京天安门,我告诉你需要先乘坐9号线然后转13号线。9号线和13号线就是符号引用,如果你想真正到达,你就需要去找9号线和13号线具体在哪里,然后去乘坐。9号线和13号线所在的位置就是直接引用。
四、Initialization(初始化)阶段
该阶段是为类的静态变量赋予正确的初始值。


1. static与final的搭配问题


2. <clinit>()的线程安全性

3. 类对<clinit>的主动使用和被动使用
只要是对类进行初始化这一阶段,那么就会涉及到<clinit>的主动使用。

除了以上情况外,其他的所有情况都属于被动使用。即不会进行类的初始化操作。

五、类的卸载
一个类何时结束生命周期,取决于代表它的Class对象何时结束生命周期。

方法区的GC频率也很低,部分原因也是因为想要回收方法区中的类模板的条件还是太苛刻了。类加载器一般是不可以被回收的,用户自定义的类加载器才可能被回收。
