1、类加载全过程
类加载简图
首先我们知道写好一个类后我们先javac对类进行编译,然后通过java调用我们的JVM虚拟机,对类进行加载和执行。
下面我将结合实际的例子来对类加载机制进行一个讲解,以下讲解是类加载过程的初级分析,且我们跳过编译的阶段,直接从JVM的调用开始。其实这也是我学习的一个部分,学习之后的消化往往是你学习的关键。
测试代码:
package com.maple.jvm;
public class Test {
public static String name="World";
public static void main(String[] args) {
A a = new A();
System.out.println(a.name);
}
}
class A{
public static String name="Hello";
static {
System.out.println("A静态数据加载");
}
public A() {
System.out.println("创建A对象");
}
}
1、加载过程
类的加载过程就是将字节码文件写入内容,并将其中的静态数据转化为方法区中的运行时数据结构,可以简单的理解为类的模板信息,同时在堆中生成一个java.lang.Class对象来代表这个类,来作为方法区数据结构的入口,这个过程需要类加载器的参与。
结合以上代码的例子给出这个过程的内存图分析如下:
截图分析:
首先由于是在Test类的main方法中调用A类,所以先对Test类进行加载操作,如上图所示,在方法区中形成了Test类的运行时数据结构,同时在堆中生成对应的java.lang.Class对象来代表Test类,然后同样的道理,对A类也进行同样的加载操作。
2、链接过程
a、验证
及检查对应的运行时数据结构是否符合JVM虚拟机规范,是否会对JVM虚拟机曹成影响
b、准备
在方法区中正式为类变量(static变量)分配内存并设置类变量初始值的阶段,注意这里并不等于赋值,类变量的赋值操作是在初始化阶段执行的
c、解析
为方法区中的符号引用分配实际的内存地址,转化为直接引用。
3、初始化过程
编译器自动收集类变量的赋值信息和static静态初始化块中的语句合并为类构造器<clinit>()并执行的过程。可以理解为类变量赋值并执行static块中的语句。
4、使用和初始化过程这里不作为重点进行讲解
小结:这只是类加载机制的一个大致的过程,先了解大概和纲要再根据具体要求进行学习效果会好得多。
其实类加载机制就三个主要的部分,加载,链接,初始化,加载过程就是将类中的静态数据转化为运行时数据结构保存在方法区中,同时生成代表Test类的java.lang.Class对象;链接过程最主要的就是将符号引用变为直接引用也就是为这些符号赋予直接的地址;最后就是初始化阶段,这个阶段主要是进行赋值操作。