`
annan211
  • 浏览: 446178 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

字节码验证 的高度对jvm的优化

    博客分类:
  • jvm
 
阅读更多
程序员对虚拟机的优化大多集中在堆栈的分配以及和内存大小的调节的层面上,在这个层面上的调节也是jvm影响最大的部分。但是我们仍然可以从比较细的层面上对jvm进一步优化。
稍微进一步,是对 方法区,Java虚拟机栈,本地方法栈,堆,甚至程序计数器方面进行点滴的优化。
再小一点,我们先来理解一个概念。
在虚拟机执行子系统中存在一个类加载过程,这个过程包含加载、验证、准备、解析、和初始化,当然,在类加载之后还应当包含执行和卸载这两个阶段。
  加载即是虚拟机通过一个类的全限定名来获取定义此类的二进制字节流。(全限定名:com/sun/Summer),然后将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。(运行时数据结构前面已经介绍,即堆、方法区、本地方法区、Java虚拟机栈、程序计数器)   然后虚拟机在堆上生成一个java.lang.Class对象,作为访问方法区的一个外部入口。

接下来是验证,验证是连接阶段的第一步,是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。验证阶段非常重要,并且验证阶段的工作量在虚拟机的类加载子系统中占了很大一部分,所以我们有必要在码代码的时候,注意Jvm的这一特性,就可以获得可观的虚拟机回报。
  验证阶段包含 文件格式验证、元数据验证、字节码验证和符号验证四个阶段。
  1 文件格式验证比较简单,主要是验证版本、常量类型、字符编码以及引用地址。当然其实际验证要远远不止这些而且要复杂的多。
  2 元数据验证 主要检查类 是否有父类,是否实现了必要的方法,是否被非法继承,等等。
  3 字节码验证  ,字节码验证是最复杂的一个阶段,主要是进行数据流和控制流的分析。
主要对类的方法体进行安全验证。包括 非法类型转换,跳转指令跳转到方法体之外,无限循环等等,由于数据流验证的高复杂性会在一定程度上拖慢虚拟机,所以我们在码代码的时候,尽量避免使用一些类型推导类的手段去实现,尽量使用类型检查来减少虚拟机检查时间。
jdk 1.6 之后的javac 提供了 StackMapTable 属性,这一属性可以将字节码验证的类型推导转化为类型检查从而节省一些时间。
我们也可以通过在 JDK 1.6 -XX:-UseSplitVerifier 来关停javac 编译器中的 StackMapTable 优化属性,或者通过-XX:+FailOverToOldVerifier 要求在类型校验失败的时候回退懂啊旧的类型推导方式进行校验。


如果所运行的代码(包括自己写的和第三方的代码) 都已经被反复使用和验证过,在实施阶段就可以考虑使用 -Xverify:none 参数来关闭大部分的类验证措施,以缩短虚拟机在类加载阶段的耗时。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics