class 类 什么 时候被 加载 java虚拟机内存
2个回答
展开全部
编写的java文件经过编译之后形成字节码文件,当你的程序在运行中调用到该class类的时候,通过ClassLoader进行加载。下面详细介绍下。
class文件从加载到jvm内存中开始,到卸载出内存为止,他的整个生命周期(整个加载过程)包括:加载,验证,准备,解析,初始化,使用和卸载。其中验证,准备,解析三个合称为连接。下面重点说一下加载过程。
加载过程:
1、通过一个类的全限定名来获取定义此类的二进制字节流
2、将字节流所代表的静态存储结构转化为方法区的运行时存储结构
3、在java堆中生成一个代表该类的对象,作为方法区这些数据的访问入口
验证:
1、文件格式验证:是否以魔数0xCAFEBABE开头,class文件的主次版本号是否在当前jvm处理范围之内,常量池的常量中是否有不被支持的类型,指向常量中的索引值有无不存在的常量,等
2、元数据验证:对字节码描述的信息进行语义分析,保证符合java规范。如是否有父类,是否继承了不允许继承的类,如果不是抽象类,是否实现了所有未实现的方法。等
3、字节码验证:数据流和控制流分析。主要针对类的方法体。
4、符号引用验证:如符号引用中通过字符串描述的全限定名是否能够找到对应的类等
准备:
该阶段正式为类变量分配内存并设置初始值。内存在方法区中分配。这里说的初始值是通常情况下说的零值。
解析:
虚拟机将常量池中的符号引用替换为直接引用的过程。包括:
1、类或接口的解析
2、字段解析
3、类方法解析
4、接口方法解析
初始化:
类初始化阶段是类加载过程的最后一步,除了加载阶段用户可以通过自定义加载器参与外,其余动作完全由虚拟机指导控制。到了初始化阶段,才真正开始执行类中定义的java程序代码(字节码)。在准备阶段,变量已经赋过一次系统默认值,而在初始化阶段,则是根据程序制定的主观计划去初始化类变量和其他资源,即初始化阶段是执行类构造器<clinit>()方法的过程。<clinit>是在编译java源码时,按照静态块和静态变量赋值语句的顺序生成的。如果类没有静态块也没有为静态变量赋值,就不会生成<clinit>方法,该方法只能被虚拟机调用。
class文件从加载到jvm内存中开始,到卸载出内存为止,他的整个生命周期(整个加载过程)包括:加载,验证,准备,解析,初始化,使用和卸载。其中验证,准备,解析三个合称为连接。下面重点说一下加载过程。
加载过程:
1、通过一个类的全限定名来获取定义此类的二进制字节流
2、将字节流所代表的静态存储结构转化为方法区的运行时存储结构
3、在java堆中生成一个代表该类的对象,作为方法区这些数据的访问入口
验证:
1、文件格式验证:是否以魔数0xCAFEBABE开头,class文件的主次版本号是否在当前jvm处理范围之内,常量池的常量中是否有不被支持的类型,指向常量中的索引值有无不存在的常量,等
2、元数据验证:对字节码描述的信息进行语义分析,保证符合java规范。如是否有父类,是否继承了不允许继承的类,如果不是抽象类,是否实现了所有未实现的方法。等
3、字节码验证:数据流和控制流分析。主要针对类的方法体。
4、符号引用验证:如符号引用中通过字符串描述的全限定名是否能够找到对应的类等
准备:
该阶段正式为类变量分配内存并设置初始值。内存在方法区中分配。这里说的初始值是通常情况下说的零值。
解析:
虚拟机将常量池中的符号引用替换为直接引用的过程。包括:
1、类或接口的解析
2、字段解析
3、类方法解析
4、接口方法解析
初始化:
类初始化阶段是类加载过程的最后一步,除了加载阶段用户可以通过自定义加载器参与外,其余动作完全由虚拟机指导控制。到了初始化阶段,才真正开始执行类中定义的java程序代码(字节码)。在准备阶段,变量已经赋过一次系统默认值,而在初始化阶段,则是根据程序制定的主观计划去初始化类变量和其他资源,即初始化阶段是执行类构造器<clinit>()方法的过程。<clinit>是在编译java源码时,按照静态块和静态变量赋值语句的顺序生成的。如果类没有静态块也没有为静态变量赋值,就不会生成<clinit>方法,该方法只能被虚拟机调用。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询