每天一个java类_【每天进步一点点】java类加载机制

当用java命令运行某个main函数时,首先需要类加载器把主类加载到JVM内存中。

下面就是一个class文件大致的加载流程:

5a2388105e2605cc8169961bf61b8bb9.png

如上图 将编译好的字节码class文件通过java命令,在win操作系统就是一个java.exe文件,这个文件底层是c++语言实现的,通过这个文件调用底层jvm.dll文件创建Java虚拟机,这个jvm.dll文件也是c++语言实现的就是一些类库。在创建JVM虚拟机的过程中会通过c++语言创建一个引导类加载器。最终由C++语言调用java代码创建JVM启动器Launcher,该类由引导类加载器创建其他类加载器,最终调用的Launcher类的getLauncher()方法,这个方法创建加载了扩展类加载器,应用程序类加载器。最终调用loadClass()方法实现类的加载。

其中loadClass的类加载过程有如下几步:

82b851e4448e80642c039dd47685952d.png

加载

在硬盘上查找并通过IO读入字节码文件,使用到类时才会加载,例如调用类的main()方法,new对象等等,在加载阶段会在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

验证

校验字节码文件的正确性,不会危害虚拟机自身的安全

d66020c45cda21d7d1322a5e88e0ba1d.png

准备

给类的静态变量分配内存,并赋予默认值

数据类型

零值

int

0

long

0L

short

(short)0

char

'u0000'

byte

(byte)0

boolean

false

float

0.0f

double

0.0d

reference

null

解析

将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如

main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态链接过

程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为直接引用

初始化

对于初始化阶段,虚拟机严格规范了有且只有5种情况下,必须对类进行初始化(只有主动去使用类才会初始化类):

当遇到getstatic、putstatic或invokestatic 这4条直接码指令时,比如读取一个静态字段(未被 final 修饰)、或调用一个类的静态方法时。

使用new关键字实例对象。

使用 java.lang.reflect 包的方法对类进行反射调用时如Class.forName(""),newInstance()等等。如果类没初始化,需要触发其初始化。

初始化一个类,如果其父类还未初始化,则先触发该父类的初始化。

当虚拟机启动时,用户需要定义一个要执行的主类 (包含 main 方法的那个类),虚拟机会先初始化这个类。

当一个接口中定义了JDK8新加入的默认方法(被default关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,那该接口要在其之前被初始化。

卸载

卸载类需要满足3个要求:

该类的所有的实例对象都已被GC,也就是说堆不存在该类的实例对象。

该类没有在其他任何地方被引用

该类的类加载器的实例已被GC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值