《Oracle JRockit: The Definitive Guide》一书是由Oracle JRockit的两位资深开发人员写的,其中的Marcus Hirt更是JRockit Mission Control的leader,这本书详细的对Oracle JRockit进行了介绍,最突出的特点非常系统化的介绍了一个JVM通常是如何实现的,而JRockit这样一个极为优秀的JVM又是做了哪些优化,为什么做这些优化,这本书对于对JVM感兴趣的同学而言应该是必读的一本书,其实即使对于JVM兴趣不强的同学,里面的优化思路的介绍也是值得学习,本系列的blog主要是总结看这本书得到的一些收获,由于书中知识量巨大,因此得分成多篇blog来总结了。
书的第二章为:Adaptive Code Generation,在这章中作者向我们讲解了一个优秀的JVM是如何来实现代码的高效执行的,感兴趣的同学其实可以在不看下面blog内容之前,先考虑下如果是你做的话,你会怎么做来实现Java代码的高效执行呢,然后再对比下这章的内容,我想你能学到很多的,:)
用过Java的同学都知道,Java是通过javac将Java源码编译为class文件,然后通过ClassLoader装载此class文件,之后就可执行此class了,要最高效的执行这个class,最好的方法莫过于class文件直接就是机器码,这样直接执行就可以了,但Java是跨平台的,因此class文件就不能是机器码了。
由于class文件不是直接的机器码,要执行它最简单的方法就是采用纯粹的解释方式,解释方式由于每次都得将class文件中的指令翻译为对应的机器环境的指令,效率是很低的。
为了能更高效的执行,同时又保持跨平台的特性,另外一个方法就是在执行class时再将其翻译为对应的机器码,这个方法是比较靠谱的,因此无论是 Hotspot、还是JRockit,都采用了这种方式,也就是大家熟知的JIT(Just In Time) Compiler。
OK,既然觉得在装载class后翻译成机器码去执行可以比较高效,那这个时候又会出现两种状况,是执行class的时候就立刻翻译成机器码,还是先用解释模式执行,然后到一定时机再翻译成机器码呢,之所以出现这两种状况,原因在于将class翻译为机器码是需要消耗时间的,因此如果执行class 的时候就立刻翻译成机器码的话,也就会导致Java程序启动速度会比较慢,JRockit是这么认为的,JRockit的服务对象是server级应用,这类应用的特点是没那么在乎启动速度,而更在乎的是执行时的高效,而且如果执行的时候就立刻翻译成机器码的话,就意味着压根不需要实现解释器,因此 JRockit采取的方法是在执行class时直接编译为机器码,而Hotspot由于需要同时支持client和server应用,对于client应用而言,启动速度非常重要,因此Hotspot采用的是先解释执行,到了一定时机后再翻译成机器码。
如果认为就这样就完成了Java代码的执行的实现,那就太小看JVM了,由于JVM能够知道代码运行的全部状况,自然还可以做出更多更出色的提升代码执行速度的优化,例如标量替换、更好的inline等,后面再来细说,因此这样就出现了一个状况,什么时候对哪些代码来做这些更猛的优化呢。
真正值得做更猛的优化的代码自然是所谓的”热点”代码,如何来发现哪些代码是热点代码呢,通常有三种方法:
1、方法调用计数器
方法调用计数器是常见的方式,hotspot采用的即为这种,这种方式不好的地方就在于计数器本身经常是cpu cache misses的,因此稍微会有点影响性能。
2、对线程进行采样
可采用软件或硬件方式来实现,软件方式实现不好的地方在于采样的时候需要暂停线程,好处是因为是采样,不需要对所有方法进行计数,硬件方式自然是最好的,但不是所有的硬件都支持的,支持的硬件中最典型的是intel IA-64的CPU。
在有了发现热点代码的方法后,接下来需要做的就是更猛的优化,有很多种,例如Java的代码中,通常会是接口方式的调用,但因为是接口方式的调用,所以其实默认情况下是不好做inline处理的,但JVM为了更高效的执行代码,如发现这代码为热点代码,那么就会做一些激进的优化,例如会假设这个接口只有一个实现,然后就可以直接将此实现对应的代码inline进来了(至于为什么inline后效率更高,这个请参考编译原理之类的书),这些激进优化同样适合于if、抛异常这些状况,当然,当激进优化的条件失效时,就会逆优化回到之前基本编译的代码。
而其他的更猛的优化还包括根据线程执行路径进行逃逸分析等,后面再专门写一篇blog来讲解下一些翻译为机器码的优化吧,其实大多都是编译原理的一些东西。
书中在介绍JRockit如何实现自己的JIT Compiler时,提到了Bytecode混淆以及bytecode优化,JRockit的态度是bytecode混淆时将name进行混淆是靠谱的,但如果对control flow进行混淆,就不太好了,因为这有可能会导致jit compile时的有些优化也做不了了,而bytecode优化,JRockit的态度是应该避免,因为没什么太大的意义,更主要的优化还是得靠jit compiler。
JRockit的JIT Compiler的实现和Hotspot另外一个很大的不同在于JRockit并未采用on-stack replacement,据JRockit的研究,这个没有太大必要,当然,对于编写benchmark代码时则要注意这个不同。
JIT Compiler在compile时还需要考虑的几个重点问题:
1、为GC提供必要的信息;
2、为查错提供必要的信息,例如代码的行数、变量名等;
从这章的内容可以看到,JRockit为了能够让Java代码能够高效的执行,是做出了非常多的努力的,也可以看到很多JRockit与Hotspot不同的地方,甚至可以看出Java代码的执行比C代码的执行高效都是有可能的,:)。
--转载 淘宝JAVA中间件团队博客 JRockit读书笔记I — Java代码的高效执行
http://rdc.taobao.com/team/jm/archives/585
分享到:
相关推荐
JAVA设计模式提高反射效率,Java代码精粹,高手实现,高效java代码,反射高效代码,绝对受益 JAVA设计模式提高反射效率,Java代码精粹,高手实现,高效java代码,反射高效代码,绝对受益 JAVA设计模式提高反射效率,...
Java代码自动生成工具是一种高效开发辅助软件,它能够根据预设的模板或规则,自动创建出符合特定规范的Java源代码。这样的工具极大地提升了开发效率,减少了程序员在编写重复性结构化代码上的时间,使他们可以更加...
Java代码统计工具是一款专为Java开发者设计的实用小软件,旨在帮助程序员高效地分析和量化他们的代码库。这款工具能够提供一系列详细的统计信息,有助于理解项目中的代码结构和质量。以下将详细介绍该工具的主要功能...
总的来说,Elasticsearch的Java实现涵盖了索引生命周期管理、查询构建和执行等多个方面,通过Java代码可以灵活地进行数据操作,实现高效的数据检索和分析。开发者需要对Elasticsearch的原理有深入理解,并掌握Java ...
主要代码审计方法是跟踪用户输入数据和敏感函数参数回溯: 跟踪用户的输入数据,判断...这个方法是最高效,最常用 的方法。大多数漏洞的产生是因为函数的使用不当导致的,只要找到这些函数,就能够快速挖掘想要的漏洞。
本文将深入探讨如何在Python中调用Java代码,实现两者之间的有效通信。 首先,我们需要理解Python和Java之间的调用机制。Python提供了多种方式来调用Java代码,其中最常见的是使用Jython(Python的Java实现)和...
在实际应用中,Java代码可能会通过Ajax发送一个请求到服务器,服务器解析请求后调用对应的JS函数,例如在"des.js"中执行解密操作,然后将结果返回给Java。"des.html"可能是展示解密结果的界面,"des.java"负责处理...
当Java代码需要执行JavaScript时,可以使用`WebView`的`loadUrl()`或`evaluateJavascript()`方法。`loadUrl()`通常用于加载整个网页或者执行一段JS代码,例如: ```java webView.loadUrl("javascript:...
下面是一个简单的使用`ScheduledExecutorService`实现延迟执行的Java代码示例: ```java import java.util.concurrent.*; public class DelayExecutionDemo { public static void main(String[] args) { // 创建...
在Java开发过程中,经常需要与数据库进行交互,尤其是在处理大量数据时,如何高效地执行SQL语句变得尤为重要。本文将详细介绍如何利用Java进行批量SQL执行,包括其背景、实现原理、代码示例及优化策略等。 #### 一...
Java代码管理器是一款基于Java语言开发的工具,用于高效地组织、存储和管理代码文件。在软件开发过程中,代码管理是至关重要的,它可以帮助开发者跟踪代码版本,协同工作,以及保持代码库的整洁和有序。Java作为一款...
本资源包"JAVA代码、方法、运算符大全"是针对Java初学者和进阶者的一份宝贵资料,它涵盖了Java编程中的核心元素:代码、方法和运算符。 一、Java代码 Java代码是实现特定功能的指令集合,它由类(Class)、方法...
Java代码反编译工具是程序员在特定情况下非常有用的工具,主要用于查看和理解Java字节码(.class文件)的原始源代码。这类工具能够将已编译的Java类文件转换回接近原始的Java源代码形式,尽管可能无法完全恢复到与...
例如,MyBatis Plus和generator-plus是Java领域常用的代码生成器,它们可以根据数据库表结构生成对应的Java代码。 快速开发不仅仅是选择合适的工具,还需要良好的开发流程和规范。Docker容器化部署可以帮助团队在...
Java定时执行任务是Java开发中常见的一种需求,用于在特定时间点或按照预设周期执行某段代码。在Java中,有两种主要的方式来实现定时任务:Java.util.Timer类和java.util.concurrent包下的ScheduledExecutorService...
Java代码生成器是一款高效实用的开发工具,专为Java程序员设计,旨在提高开发效率,减少重复劳动。通过自定义模板和规则,它能够自动化生成常见的业务逻辑代码、数据访问层(DAO)、服务层(Service)、控制器...
本方案旨在提供一个详细的检查计划,帮助开发者识别并解决Java代码中的性能瓶颈,以提高程序的执行效率。 前言 Java程序的性能优化是提升软件质量的关键步骤,它涉及到内存管理、线程调度、数据结构选择等多个方面...
JVM通过其解释执行机制和即时编译技术,使得Java程序具备了良好的平台无关性和高效的执行性能。 研究Java虚拟机的解释执行机制,不仅有助于深入理解Java程序的执行过程,也为计算机研究人员和从业者提供了底层技术...
总的来说,Java 使用 DataX 增量同步代码的优势在于高效、稳定和易扩展。它能帮助开发者快速构建起数据同步流程,同时提供灵活的配置选项以适应各种复杂的数据迁移需求。通过以上步骤,你可以将这个功能直接集成到你...
例如,你可以在Java服务端定义一个接口,该接口允许在运行时加载和执行JavaScript脚本来完成特定任务,这样就能轻松地切换或更新业务逻辑,而无需重新编译和部署Java代码。 在实际项目中,这种方法可以应用于许多...