面试回答第十五问:类加载

类加载简介

类加载是JVM能够识别类信息,分配空间创建对象实例的基础。

类加载一共分为五阶段,分别是加载,验证,准备,解析,初始化五阶段。这不是顺序,不是加载之后才能验证,验证之后才能准备。下面我会提到具体执行顺序。

加载

首先加载阶段就是我们写一个.java文件被编译成.class二进制字节码文件,之后转换成JVM规定的运行时数据结构Klass模板,类信息全都在Klass中,之后创建对象实例就是依靠Klass指示,分配多大内存啊,有什么静态变量等等。

验证

验证阶段有四个验证,分别是字节码验证,文件格式验证,元数据验证以及符号验证。像字节码验证这个是在加载阶段之前做的,保证字节码是安全的;其次文件格式和元数据是针对加载阶段得到的Klass做的,验证Klass文件格式以及它存储的元数据的安全;最后的符号验证是在解析阶段之前做的,验证符号是否有对应的直接地址,比如方法内引用的类是否已被加载,比如Test类的main方法中执行new User,那么针对Test类加载中的符号验证就是要验证User类是否已被类加载,没有就先加载User类。

准备

准备阶段就是把类的静态变量全部赋默认值,比如static int赋0,引用赋null,赋值赋的是类型默认值。

解析

解析阶段就是把符号引用转成直接引用,比如main方法内要执行一行new User方法,这个User在没解析之前就是一个符号,解析就是把这个符号映射到User类的Klass地址,这就是直接引用,直接引用User类的Klass,这样执行时就可根据Klass创建实例对象,至于符号引用与直接引用的映射,这个放到了常量池中,常量池也是方法区的一部分,我多介绍一点,我想把JVM的方法区介绍的透彻一点,方法区是以Klass为单位存储类元数据,那Klass中也是有划分的,比如类的字段,类的继承信息,类的方法,常量池等等,其中类的每个方法都有一个Method对象,里面存储方法的字节码。比如main方法的第二行代码new User,编译成字节码后变成new #2,这个#2就是User类在Test类的main方法的代号,在没做解析之前,这就是一个普通的代号,在解析之后,#2这个代号指向User类的Klass地址,这个映射在常量池中,当main方法执行时就从常量池中取出映射找到User的Klass,指导JVM分配堆内存。

初始化

初始化阶段就是为类中的静态变量赋指定初始值。

至此类加载结束,

相关推荐
maqr_1102 分钟前
HTML怎么生成订单预览_HTML只读订单信息结构【操作】
jvm·数据库·python
2301_8038756127 分钟前
如何通过phpMyAdmin给WordPress所有用户发送全站通知_系统表插入
jvm·数据库·python
M ? A36 分钟前
Vue 动态组件在 React 中,VuReact 会如何实现?
前端·javascript·vue.js·经验分享·react.js·面试·vureact
2301_777599371 小时前
mysql如何进行数据库容量规划_评估磁盘空间增长趋势
jvm·数据库·python
m0_377618232 小时前
Redis怎样应对大规模集群的重启风暴_分批次重启节点并等待集群状态恢复绿灯后再继续操作
jvm·数据库·python
2401_835956812 小时前
Golang怎么写基准测试benchmark_Golang基准测试教程【完整】
jvm·数据库·python
小欣加油2 小时前
leetcode2078 两栋颜色不同且距离最远的房子
数据结构·c++·算法·leetcode·职场和发展
zhangchaoxies4 小时前
golang如何使用SQLx原生SQL查询_golang SQLx原生SQL查询使用方法
jvm·数据库·python
m0_743623924 小时前
mysql如何优化InnoDB缓冲池大小_mysql缓冲池内存调优
jvm·数据库·python
m0_617881424 小时前
如何操作 XML 数据_XMLTYPE 与 EXTRACT 函数解析节点
jvm·数据库·python