天天看点

如何避免warm up现象?

[size=large][color=blue]1. warm up会有什么影响?[/color][/size]

·这也是我为什么要讲这个话题的原因。主要是因为我们经常自己写代码测试某些方法的性能([url=http://baike.baidu.com/view/1854349.htm]基准测试[/url]),发现每次运行的时间都不一样,甚至方法的顺序,方法的大小,测试结果也可能会不一样。

·影响基准测试结果的因素有很多:比如硬件配置:单核,双核,内存大小;jvm机制:执行方式,堆管理(GC),hotspot优化策略,并发等。

·我们要尽量减少这些因素的干扰,其中warm up现象就是一个要避免的。

[size=large][color=blue]2. 那什么是warm up现象?[/color][/size]

·中文说法--预热。为什么会有预热现象了?先说说jvm几种执行方式。

·jvm有四种执行方式:解释执行,编译执行,动态优化执行(自适应优化),芯片级直接执行。

·动态优化执行:虚拟机开始对所有代码都是解释运行,但是它会监视代码的执行情况,找出频繁执行的代码,然后编译成本地代码,同时采取一些策略优化编译后的代码。这个执行时编译的过程也叫动态编译或即时编译。

·sun hotspot jvm采用的就是动态编译方式(SUN的JDK版本从1.3.1开始运用HotSpot虚拟机)。

·那么解释执行代码,直到将程序编译成本地代码,这个过程可以理解为jvm warm up。

[size=large][color=blue]3. 怎么避免warm up带来的影响了? [/color][/size]

[b]·方法一:jvm参数设置[/b]

-XX:CompileThreshold=10000:参数意思:通过JIT编译器,将方法编译成机器码的阀值,可以理解为调用方法的次数。client模式默认1500,server模式默认10000。

有些资料建议指定为1,第一次运行的时候就编译成本地代码。这样会达到预期的效果吗?

我们先看几个例子:(我们通过参数 -XX:+PrintCompilation往stdout打印方法被JIT编译时的信息来观察JNI的过程)

A)XX:CompileThreshold=1;调用iteratorloop方法10000次,编译信息:

·输出了很多编译信息,但是并没有编译iteratorloop方法

B)XX:CompileThreshold=1;调用iteratorloop方法100000次,编译信息:

·编译了iteratorloop方法(第三行信息,只拷贝了一部分)

C)XX:CompileThreshold=1500;调用iteratorloop方法1499次,编译信息:

·只打印了三次编译信息,没有编译iteratorloop方法。

D)XX:CompileThreshold=1500;调用iteratorloop方法1500次,编译信息:

·编译了iteratorloop方法(第四行信息)

【结论】

·CompileThreshold=1,遍历10000次后才可能发生编译;CompileThreshold=1500,编译的方法少,并且遍历1500次时,iteratorloop被编译执行了。

·jvm执行程序的时候,本身会调用很多方法(从打印出的编译信息可以看出),所以你想测试的方法不一定是执行频率最高的方法,这完全取决于jvm的hotspot策略。或者说CompileThreshold只是个先决条件,达到了这个值,不一定就会马上编译,虚拟机中会采取策略选择它所认为的当前hotspot编译成本地方法。

[b]·方法二:先执行测试方法N次;然后在测试某方法执行时间。[/b]

·配合方法一:先预设CompileThreshold一个阀值,并通过PrintCompilation确认程序执行指定N次后会编译成本地代码。

{参考资料}

[url=http://rdc.taobao.com/team/jm/archives/552]大方法的执行性能与调优过程小记[/url]

[url=http://www.ibm.com/developerworks/cn/java/j-benchmark1.html]健壮的 Java 基准测试,第 1 部分: 问题[/url]

[url=http://www.ibm.com/developerworks/cn/java/j-benchmark2/index.html]健壮的 Java 基准测试,第 2 部分: 统计和解决方案[/url]

[url=http://www.infoq.com/cn/articles/java-threading-optimizations-p2]Java 6中的线程优化真的有效么[/url]