Java 6中的线程优化真的有效么?——第二部分 - 编程入门网
,直到所有代码都已经完成了JIT化。 这个预热的阶段通常被称为“预热方法的缓存 ”。
大多数JVM会同时运行在解释的与本机的模式中。这就是所谓的混合模式执行 。随着时间的流逝,Hotspot和JIT会根据收集的信息将解释型代码转化为本机代 码。Hotspot为了决定应该使用哪种优化方案,它会抽样一些调用和分支。一旦某 个方法达到了特定的阈值后,它会通知JIT生成本机代码。这个阈值可以通过- XX:CompileThreshold标记来设定。例如,设定-XX:CompileThreshold=10000, Hotspot会在代码被执行10,000次后将它编译为本机代码。堆管理 下一个需要考虑的是垃圾收集,或者更广为人知的名字—堆管理。在任何应用 程序执行的过程中,都会定期地发生很多种内存管理活动。它们包括:重新划分 栈空间大小、回收不再被使用的内存、将数据从一处移到另一处等等。所有这些 行为都导致JVM影响你的应用程序。我们面对的问题是:基准测试中是否需要将内 存维护或者垃圾回收的时间包括进来?问题的答案取决于你要解决的问题的种类 。在本例中,我只对获取锁的开销感兴趣,也就是说,我必须确保测试中不能包 含垃圾回收的时间。这一次,我们又能够通过异常的现象来发现影响测试的因素 ,一旦出现这种问题,垃圾回收都是一个可能的怀疑对象。明确问题的最佳方式 是使用 -verbose:gc标志,开启GC的日志功能。 Java 6中的线程优化真的有效么?——第二部分(2)时间:2011-05-20 infoq.com Jeroen Borgers 译:韩锴在这个基准测试中,我做了大量的String、StringBuffer和StringBuilder操 作。在每次运行的过程中大概会创建4千万个对象。对于这样一种数量级的对象群 来说,垃圾回收毫无疑问会成为一个问题。我使用两项技术来避免。第一,提高 堆空间的大小,防止在一个迭代中出现垃圾回收。为此,我利用了如下的命令行 :
然后,加入清单1的代码,它为下一次迭代准备好堆空间。
清单1. 运行GC,然后进行短暂的休眠。 休眠的目的在于给垃圾回收器充分的时间,在释放其他线程之后完成工作。有 一点需要注意:如果没有CPU任何活动,某些处理器会降低时钟频率。因此,尽管 CPU时钟会自旋等待,但引入睡眠的同时也会引入延迟。如果你的处理器支持这种 特性,你可能必须要深入到硬件并且关闭掉“节能”功能才行。 前面使用的标签并不能阻止GC的运行。它只表示在每一次测试用例中只运行一 次GC。这一次的暂停非常小,它产生的开销对最终结果的影响微乎其微。对于我 们这个测试来说,这已经足够好了。 偏向锁延迟 还有另外一种因素会对测试结果产生重要的影响。尽管大多数优化都会在测试 的早期发生,但是由于某些未知的原因,偏向锁只发生在测试开始后的三到四秒 之后。我们又要重述一遍,异常行为再一次成为判断是否存在问题的重要标准了 。-XX:+TraceBiasedLocking标志可以帮助我们追踪这个问题。还可以延长预热时 间来克服偏向锁导致的延迟。 Hotspot提供的其他优化 Hotspot不会在完成一次优化后就停止对代码的改动。相反,它会不断地寻找 更多的机会,提供进一步的优化。对于锁来说,由于很多优化行为违反了 Java存 储模型中描述的规范,所以它们是被禁止的。然而,如果锁已经被JIT化了,那么 这些限制很快就会消失。在这个单线程化的基准测试中,Hotspot可以非常安全地 将锁省略掉。这样就会为其他的优化行为打开大门;比如方法内联、提取循环不 变式以及死代码的清除。 如果仔细思考下面的代码,可以发现A和B都是不变的,我们应该把它抽取出来 放到 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |