Java JIT编译:不仅仅是个流行词

本文由 ImportNew - 唐尤华 翻译自 javacodegeeks

最近我遇到了一个Java产品性能问题,强迫我重新熟悉并且深感Java即时(JIT)编译器对我的帮助。大多数Java开发者和支持人员都听说过JVM运行时性能优化,但是究竟有多少人真正理解并从中受益?

本文将会分享我曾经遇到的一个问题及解决过程,并附带了新虚拟机服务器的配置过程(扩容和水平扩展工程)。

为了更深入地讨论JIT,我推荐下列文章:

即时编译:http://en.wikipedia.org/wiki/Just-in-time_compilationJava HotSpot性能引擎架构:http://www.oracle.com/technetwork/java/whitepaper-135217.html理解即时编译及优化:http://docs.oracle.com/cd/E15289_01/doc.40/e15058/underst_jit.htmJIT编辑器如何优化代码:http://pic.dhe.ibm.com/infocenter/java7sdk/v7r0/index.jsp?topic=%2Fcom.ibm.java.zos.70.doc%2Fdiag%2Funderstanding%2Fjit_overview.html
JIT编译概述:

JIT编译本质上是改进Java应用程序运行时性能的过程。

下图展示了JVM不同层次间的交互,描述了高层次的流程:

    Java源码通过编译器转为平台无关的字节码(bytecode)或Java class文件。在启动Java应用程序后,JVM会在运行时加载编译后的类并通过Java解释器执行适当的 语义计算。当开启JIT时,JVM会分析Java应用程序的函数调用并且(达到内部一些阀值后)编译字节码为本地更高效的机器码。JIT流程通常为最繁忙的函数调用提供更高的优先级。一旦函数调用被转为机器码,JVM会直接执行而不是“解释执行”。上述过程会在程序运行过程中不断提高性能。

案例分析

现在要介绍一下我之前提到的项目背景。项目的主要目标是为产品环境添加一台新的IBM P7 AIX 虚拟服务器以提高平台性能。下面是平台的一些参数:

Java EE服务器:IBM WAS 6.1.0.37 &IBM WCC 7.0.1OS:AIX 6.1JDK:IBM J2RE 1.5.0 (SR12 FP3 +IZ94331) @64-bitRDBMS:Oracle 10g平台类型:中间层和批处理

为了达到现有应用程序的性能水平采购了同样配置的硬件,AIX OS和其他IBM软件也都安装了和产品环境相同的版本。

下面的清单是所有为了确认应用程序性能一致需要验证的内容:

硬件规格(CPU核、物理内存、存储器域网等)OS 版本和补丁级别,包括AIX内核参数IBM WAS & IBM WCC版本、补丁级别,包括调整参数IBM JRE版本、补丁级别和调整参数(启动参数、Java堆大小等)还要仔细设置网络连接和性能

在新产品构建服务器安装完成后,需要进行功能测试确保在线和批处理程序性能良好。

然而,在第一天运行产品时发现了一个重大的性能问题。你可以看到一组性能数据汇总:

产品服务器操作运行时间处理容量(# 请求)CPU %(均值)中间件健康程度 现有服务器10 hours250 000 (基线)20%健康新服务器10 hours50 000 -500%80% +400%大量占用线程

正如你从上面看到的,第一天产品的性能非常恐怖。不仅是新产品服务器处理的请求数很少,而且物理资源的利用率比如CPU百分比与现有的产品服务器相比超出太多。

这样的情形让人非常迷惑,要知道之前花费了大量的时间确保新服务器和现有服务器保持一致。这个节点上,另一组核心人马介入调查以解决性能问题。

排错:找到罪魁祸首

排错小组兵分两路来排查下面两个方面:

确认IBM WAS容器CPU占用过高的原因,并且比较新服务器和现有服务器的CPU占用率对新服务器和现有服务器上的文件及数据进行比较

为了寻找CPU占用率高的原因,我们在IBM WAS和IBM WCC上通过IBM JVM进行AIXCPU线程分析。正如你从下面截图里看到的那样,很多线程的使用率在5-20%之间。在现有的服务器上运行分析,结果CPU线程占用率只有5%。

结论:

同类型的业务流程CPU占用率是现有服务器的3到4倍。

为了理解整个处理过程,JVM线程转储捕获了每个线程在同一时刻的数据。在我们审查了整个JVM(Java Core)转储的数据之后,马上意识到JIT没有启用!通过在JVM进程上运行java –version命令确认了问题。

这个发现非常重要,尤其是在现有的产品服务器上看到JIT是启用状态。与此同时,另一个负责比较文件的小组发现运行应用程序的AIX用户的环境变量有所不同。这些比较在之前的缺陷分析中被忽略掉了。他们的成果是发现新的AIX服务器上多出了下面一行:

1JAVA_COMPILER=NONE

根据IBM的文档,加上这个环境变量会禁用JIT。

复杂的根源分析,简单的解决方法

为了理解在我们的运行环境下禁用JIT带来的影响,不得不去弄懂它的含义。禁用JIT本质上意味着整个JVM现在都运行在解释模式。对我们的应用程序而言,完全运行在解释模式不仅会明显降低应用的吞吐量,还会增加对服务器CPU的占用率即每个请求/线程会是JIT的3到4倍CPU占用率(请记住,当JIT启用时,JVM会直接调用机器或本地代码)。

As expected, the removal of this environment variable along with the restart of the affected JVM processes did resolve the problem and restore the performnance level.

为你的应用评估JIT带来的好处

希望你会喜欢这个案例以及对JVM JIT编译流程的简短回顾。为了理解你的Java应用程序不使用JIT会带来的影响,我推荐你做下面的实验:

在启用JIT的情况下对应用进行负载测试,获取一些基线数据比如CPU占用率、响应时间、请求等禁用JIT重做上面的测试并比较结果– 扫描加关注,微信号: importnew — javacodegeeks 翻译: ImportNew.com – 唐尤华译文链接: http://www.importnew.com/5270.html[ ]累死累活不说,走马观花反而少了真实体验,

Java JIT编译:不仅仅是个流行词

相关文章:

你感兴趣的文章:

标签云: