当前位置:   article > 正文

一个类进入jvm后,它经历了什么?_一个对象进入jvm发生了什么

一个对象进入jvm发生了什么

前提思考:一个类什么时候进入jvm?

3个时间点会触发类加载

1. 虚拟机启动时,执行main()方法的时候

2. new一个对象的时候会触发类加载器

3. 读取静态字段或静态方法的时候

类进入jvm后的经历

        类从被加载到虚拟机内存中开始,到GC(垃圾回收)卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用卸载七个阶段。

        其中,加载、验证、准备、初始化、卸载 这五个阶段发生的顺序是确定的,而解析阶段不一定,它在某些特殊情况下可以在初始化阶段之后。

        另外,这7个阶段通常都是相互交叉的混合式进行的,通常会在一个阶段执行的过程中调用或激活另外一个阶段。

1. 加载

        “加载”是“类加机制”的第一个过程,在加载阶段,虚拟机主要完成三件事:

        (1)通过一个类的全名(包名+类名)获取此类的二进制字节流

        (2)讲这个字节流所代表的静态存储结构(存储格式,代码)和转化为方法区的运行时的数据结构(类信息)。

        (3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

2.验证

        验证Class文件的内容是否符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全。主要包括四种验证:文件格式验证,源数据验证,字节码验证,符号引用验证

3.准备

        为类变量分配内存并且设置该类变量的默认初始值,即零值;

        不包含用final修饰的static(常量),因为final在编译阶段就会分配了,准备阶段会显示初始化;

        不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到java堆中。

  1. public class Hello(){
  2. //类变量(静态变量):被分配在方法区中,在类加载的准备阶段初始值为0
  3. public static int a=1;
  4. //准备阶段,不处理,final在编译阶段就分配好了
  5. public final static int b;
  6. //实例变量:只会在堆中分配
  7. public int c=1;
  8. }

4.解析

将常量池内的符号引用转换为直接引用的过程。那问什么是符号引用、直接引用?
        1.符号引用:一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《java虚拟机规范》的Class文件格式中。
        ⒉.直接引用:直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。
举个栗子:

  1. String str="abc"; //str 就是符号引用,abc就是目标
  2. System.out.println(str); //打印引用符号
  3. //经过编译后,直接变成:
  4. System.out.println("abc"); //打印指针

5.卸载

卸载就是结束了类的生命周期。通常4种情况,导致卸载。

1.执行了System.exit()方法

⒉程序正常执行结束

3.程序在执行过程中遇到了异常或错误而异常终止

4.由于操作系统出现错误而导致Java虚拟机进程终止

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号