🖥️JVM类加载机制分析小记
00 分钟
2024-2-18
2024-3-28
type
status
date
slug
summary
tags
category
icon
password

前情提要

今天看到了一个关于JVM类加载的题,绞尽脑汁未做对,研究研究,题目如下
那么见证奇迹的时刻来了,输出结果为:
不知道有多少小伙伴做对了呢?反正我只是做对了20%,不及格。

理论基础

类加载生命周期

首先,我们需要铭记下面这个图片,也就是jvm加载类的生命周期。所以一个类在被使用之前,经历了加载->验证->准备->解析->初始化五个过程(有的书中也会把验证+准备+解析统一叫做连接)。
notion image
那么,每个过程,jvm都对类做了哪些不可告人的事情呢?

加载

在java程序运行之前,JVM会对类进行加载。在此过程中,JVM会把编译完成的.class二进制文件加载到内存,后续提供程序使用,用到的就是类加载器ClassLoader 。加载阶段与连接阶段的部分内容(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未结束,连接阶段就可能开始了。但是夹在加载阶段进行的动作,仍然属于连接阶段的内容。

连接-验证

验证是连接的第一步,目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危及虚拟机本身的安全。 验证阶段的四个步骤:文件格式检验、元数据检验、字节码检验、符号引用检验。
文件格式检验:检验字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理。 元数据检验:对字节码描述的信息进行语义分析,以保证其描述的内容符合Java语言规范的要求。 字节码检验:通过数据流和控制流分析,确定程序语义是合法、符合逻辑的。 符号引用检验:符号引用检验可以看作是对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验。

连接-准备

该阶段正式为类变量分配内存并设置类变量初始值。这些变量所使用的内存将在方法区中进行分配。此时进行内存分配的仅包括类变量,而不包括实例变量(实例变量将会在对象实例化时随着对象一起分配在Java堆中)。另外,在这里分配的静态类变量是将其值定义为默认值。因为在该阶段并未执行任何Java方法,正确的赋值将在初始化阶段执行。

连接-解析

该阶段虚拟机会将常量池内的符号引用替换为直接引用的过程。

初始化

这是类加载的最后一步,真正执行类中定义的字节码,也就是.class文件。 初始化阶段是执行类构造器方法的过程,以及真正初始化类变量和其他资源的过程。

名词含义以及区别

构造代码块、构造函数代码块、静态代码块区别

(1)构造代码块:直接在类中定义且没有加static关键字的代码块称为{}构造代码块。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数。比如:
(2)构造函数:用于给对象进行初始化,是给与之对应的对象进行初始化,它具有针对性,函数中的一种。比如
(3)静态代码块:static{}包裹的代码块,且静态代码只执行一次,可以通过Class.forName("classPath")的方式唤醒代码的static代码块,但是也执行一次。只执行一次的原因,百度了一下,大概是类被加载进内存中的方法区的时候调用静态代码块,而加载类到内存中只需要执行一次即可,比如
(4)特点: 1:该函数的名称和所在类的名称相同。 2:不需要定义返回值类型。 3:该函数没有具体的返回值。
(5)底层分析:通过反编译可以看到,构造代码块中的代码也是在构造方法中执行的。在编译时的编译器看来会默认将构造代码块中的代码移动到构造方法中,并且移动到构造方法内容的前面。
(6)三者的顺序 显示static代码初始化,然后是构造方法初始化,然后是构造函数初始化,并且静态代码只会初始化一次。比如测试方法
得到的结果为
(7)加上继承
假设Test3继承上面的Test2,代码如下
输出结果为
可以看出父类相同的类型,会在子类之前执行

问题分析

当方法执行时,先加载Test类,加载Test类时,会按顺序加载静态域(见四的解释A),所以先执行
然后执行
当执行该方法时,创建Test对象,就会运行Test类中的构造方法,即
然后执行
当执行该方法时,创建Test对象,就会运行Test类中的构造方法,即
然后执行
然后执行
然后执行
执行到此处,Test类的静态域加载完毕,然后开始执行main函数中的代码
当执行该方法时,创建Test对象,就会运行Test类中的构造方法,即

解释

解释A

<span id="jumpa"></span>如果在main函数中增加输出如下
则运行后的输出为
则可以看出,步骤1-8为加载类的时候输出的,9-11为main函数输出。

其他

参考文献: https://my.oschina.net/u/1458864/blog/2004785https://baijiahao.baidu.com/s?id=1633972974070851508&wfr=spider&for=pchttps://yq.aliyun.com/articles/712207http://www.sohu.com/a/225428891_819383https://blog.csdn.net/hxhaaj/article/details/81174743https://www.cnblogs.com/Heliner/p/10524699.html
  • ---------------------------------END---------------------------------
天行健,君子以自强不息;地势坤,君子以厚德载物