没有合适的资源?快使用搜索试试~ 我知道了~
前言 我们都知道,java编译的结果是字节码,不是本地机器码,这也是java跨平台的一大表现。既然java编译后是字节码,那么不能实际地在本地(物理机器)运行。java字节码运行在jvm虚拟机上面,既然这样,那么jvm虚拟机是如何加载读取一个类的信息的呢? 我们平时写完java代码生成的是class文件。后在运行的时候,虚拟机把描述类的信息从class文件加载到内存,然后再进行校验、解析和初始化等过程,后形成可以被java虚拟机“读懂”的java类型。那么从class——>java虚拟机能“读懂”的java类型是本文要讲解的内容。 类加载的时机 既然说到了类加载,那么到
资源详情
资源评论
资源推荐
Java虚拟机之类加载机制虚拟机之类加载机制
前言
我们都知道,java编译的结果是字节码,不是本地机器码,这也是java跨平台的一大表现。既然java编译后是字节码,那
么不能实际地在本地(物理机器)运行。java字节码运行在jvm虚拟机上面,既然这样,那么jvm虚拟机是如何加载读取一个类
的信息的呢?
我们平时写完java代码生成的是class文件。后在运行的时候,虚拟机把描述类的信息从class文件加载到内存,然后再进
行校验、解析和初始化等过程,后形成可以被java虚拟机“读懂”的java类型。那么从class——>java虚拟机能“读懂”的java类型
是本文要讲解的内容。
类加载的时机
既然说到了类加载,那么到底什么时候jvm才会加载某个类呢?
其实这个问题简单,肯定是运行时需要这个类的时候才会去加载啦!
具体来说,类加载分为几个阶段的:
· 加载
· 验证
· 准备
· 解析
· 初始化
· 使用
· 卸载
那么到底什么时候才开始加载类的第一个阶段?加载?
其实这个问题在不同虚拟机上面实现是不一样的,这个可以由虚拟机自己把握行。不过java虚拟机规范中明确了当遇到下
面5种情况的时候,必须初始化,此处的初始化是在加载,验证,准备,解析后的初始化,所以这几个阶段应该在其之前完
成:
· 遇到new,getstatic,putstatic,invokestatic这4条字节码指令时,如果类没有进行初始化,则先初始化。这4个字节码
常见的出现场景是:
使用new关键字实例化对象的时候
读取或设置静态字段(被final修饰,已在编译期把结果放入常量池的静态字段除外)的时候
调用一个类的静态方法的时候。
· 反射调用时,如果类没有初始化,得触发初始化。
· 当初始化一个类的时候,如果它的父类没有初始化,先触发父类初始化。
· 虚拟机启动的时候,包含main()方法的类(入口类)先初始化。
· JDK1.7动态语言支持的时候MethodHandle实例后解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法
句柄,并且这个方法句柄对应的类没有进行初始化的时候,需要先触发其进行初始化。
对于上面的5种情况,java虚拟机规范中使用的词语是“有且只有”,所以对一个类进行主动引用而进行的初始化只有上面几
种情况。其余的情况都是被动引用。
举例被动引用的情况:
· 通过子类引用父类的静态字段的时候,子类不会初始化
· 通过数组引用类的时候,不会触发其初始化
· 常亮在编译阶段会存入调用类的常量池,所以也不会触发定义类的初始化
其实除了类的加载过程,还有接口的加载过程,接口的加载过程和类的有一点不同,是上面5种情况的第三种,接口应该
是:
· 一个接口初始化的时候,并不会要求其父接口初始化
类加载的过程
加载
加载是类加载的第一个阶段,主要做的工作是:
· 通过类的全限定名来获取此类的二进制字节流
· 将这个字节流代表的静态储存结构转化成方法区运行时的数据结构
· 在内存中生成一个代表这个类的class对象,作为方法区这个类的各种数据访问入口。
这里的通过类的全限定名来获取此类的二进制字节流并不一定通过class文件来获得,也可以通过jar包或者网络来获得,
还可以是动态代理通过运算时计算生成。
验证
在类加载进内存后,第二件事做的是验证这个类的合法性,并且不会危害到虚拟机自身的安全。
因为class文件是可以“伪造”的,如果不对其加以验证, 可以在运行的时候会危害到虚拟机导致系统崩溃。
在这一个阶段,虚拟机做的事主要有:
· 文件格式验证
是否以魔术0xCAFEBABE开头
主次版本是否符合要求(是否在当前虚拟机能够处理的范围内)
常量池里面是否有不被支持的常量类型
指向常量的索引是否有指向不存在的常量或不符合类型的常量
CONSTANT_Utf8_info型的常亮是否有不符合UTF-8编码的数据
Class文件中的各个部分和文件本身是否有被删除的或附加的其他信息
and so on
· 元数据验证
这个类是否有父类(除Object)
这个类是否继承了不允许被继承的类(final修饰)
如果这个类不是抽象类,是否实现了父类和接口中的要求的所有方法
weixin_38667849
- 粉丝: 7
- 资源: 896
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0