1.加载
用.class文件为例,先把class文件放到方法区,然后将静态存储结构转化为方法区的运行时数据结构,然后在内存生成一个代表此类的java.lang.class对象,class对象比较特殊,是存在与方法区中的,作为方法区这个类中各个数据的访问入口。
几点解释:
1.什么叫静态存储结构转化为方法区的运行时数据结构?
通俗的解释就是class文件中的数据存储结构,jvm是不能直接使用的,要将这种结构转化为自己能够使用的类型。
2.验证
确保当前class文件的字节流中信息符合当前虚拟机的要求。
3.准备
准备阶段是为类变量分配内存,注意只有类变量(被static修饰),这些变量分配在方法区,并设置类变量的初始值,初始值并不是编程定义变量的值,是虚拟机分配给变量的初始值,下面给出两个例子。
Public static int value = 123;
变量在准备阶段过后,value的初始值为0,并不是123,123会在初始化阶段赋予value。
Public static Object obj = new Object();
如果是静态的对象,那么准备阶段过后,obj的值为null,对象会随着实例化在堆中分配内存,对象一定是位于堆中的。
有一种特例情况就是被final修饰的变量。如下
Public static final int value = 123, 在准备阶段就会将value的值设置为123。
4.解析
解析阶段是虚拟机将常量池中符号引用替换为直接引用的过程。
解释一下:符号引用是用一组符号描述所引用的目标,它与JVM实现的内存布局无关。直接引用是可以直接指向目标的指针,直接引用是和虚拟机实现的内存布局相关,如果有了直接引用,那么引用的目标一定在内存中存在了。
5.初始化
初始化阶段是类加载的最后一步,在准备阶段,变量已经赋值过一次系统要求的初始值,在初始化阶段是根据程序中的主观计划去初始化变量和其他资源。
总结一下,在整个类加载过程,对于变量来说,进行分配内存,初始化的只是static修饰的类变量,像其他的成员变量,局部变量,实例变量等都是程序执行阶段去进行分配内存,初始化,赋值的。