文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

Java是地球上最流行的软件开发平台,但是这不意味着它是容易理解的。 当然不是从性能的角度。不像其他大部分平台, Java在它运行的电脑和代码之间有一个Java虚拟机 (JVM)。 这种虚拟化有许多优点,但是让性能分析更复杂了。

JVM做了两件事让查找性能问题的根源更困难了。

第 1 段(可获 1.13 积分)
  1. 它为你的程序管理内存. 像C这种编程语言中, 你需要自己显式为数据分配内存并且当你使用完后需要显式释放内存 (C++也一样). 在Java中当你实例化一个对象时, JVM会为你在堆上分配需要的内存. 当对象没有被引用后, 他就会被垃圾回收器 (GC)回收.
  2. java传说中的“一次编写,到处运行”的口号意味着java类文件不包含原生指令. 相反, 它包含了你代码的半编译版本 (它和编译原理中的p-code在很多方面类似). 这些字节码在运行时转换为对应的机器指令, 无论在什么平台上. 解释字节码比直接从可执行文件中执行开销要大.
第 2 段(可获 1.83 积分)

当Java第一次运行时, JVM内部用来支持这两个功能的算法是很基本的. 在那时说Java应用的性能不如同样的c或c++版本是很公平的. Java赢得了一个"慢"的名声.

然而在最近二十一年里, Sun, Oracle和其他和Java有关的公司在很努力地提高JVM的性能. JVM的内部现在已经完全不同了. JVM提供者有各种各样的GC算法, 大多数将堆分代来利用 大多数应用符合弱待假设的事实 (大多数对象只存活很短的时间). 通过指针碰撞, Java对象空间的分配可以用6条机器指令完成, 远远快于C中的malloc. 并发和并行收集器的使用, 尤其是Zing C4收集器, 让GC的开销相比之前大大减少了. 对于字节码, 内部使用不同算法的自适应编译器 (通常指C1和C2编译器) 意味着通过一段时间的运行Java程序的的性能会非常接近 (某些情况下会超过) 编译式的原生代码. JVM可以在优化方面更棒, 通过它能及时知道对任意位置的类的加载. 甚至应用热身的问题都可以用Azul的Zing ReadyNow技术来缓解, 这项技术在运行时保存了应用的信息. 在程序启动时这些应用信息可以大幅减少分析和编译经常使用的代码的时间.

第 3 段(可获 3.83 积分)

问题在于,有些人仍然认为Java还是二十年前的性能表现。 当我在SUN公司时,我的一位同事,有一个很好的列子来说明这一点。 当他和对Java性能问题有分歧的人交谈时,他的方法是这样的:

“如果你有一个C或C ++应用程序运行缓慢,你的第一个想法是,你的代码有一些问题。 您需要分析您的代码并进行修复。 如果您的Java应用程序运行缓慢,那么为什么您的第一个假设是JVM运行缓慢并导致程序运行缓慢呢?

第 4 段(可获 1.38 积分)

他的说法当然是正确的,但并不意味着在所有情况下,Java应用程序的性能不佳不能都归结为编写的代码不足。 关于调整JVM的大量材料证明了这一点。

回到文章开始时候的问题,“我的应用程序代码或JVM造成的性能不佳?”当然,对于我们来说这是一个很难回答的问题。 

现在,当我们在这方面谈论性能时,我们主要看的是延迟。 延迟是系统响应请求需要多长时间,这可能是由许多不同的因素引起的。

第 5 段(可获 1.45 积分)

为了帮助确定是不是由应用程序的延迟引起的潜在系统延迟(从JVM到操作系统到硬件的所有事情),Azul已经创建了jHiccup。 正如我在较早的博客中写道,jHiccup的想法是在应用程序旁边运行Java代码,以使其具有与应用程序相同的效果。 它不需要对您的代码进行任何修改,因为它只需在代码旁边的单独的线程中运行。 没有互动,所以没有不利的表现影响。 为了尽量减少jHiccup本身的影响,它大部分时间都是休眠状态。 当它醒来时,它需要做的就是记录时间差异(使用纳秒分辨率测量)。 当它从休眠状态到醒来,还有一点工作涉及,但这是它的症结所在。

第 6 段(可获 1.9 积分)

jhiccup原始结果给我们一个很好的开始;现在我们有一种方法来衡量平台的延迟,它从应用程序的延迟分离(这是衡量你使用任何基准测试工具使用起来更容易)。然而,我们还需要一个明确的方法来理解结果,而不是必须在一个大的数值组的孔隙,以找出正在发生什么。Azul也开发了一个图形化的工具,将jhiccup输出(生成高动态范围图像直方图的文件)和产生易于理解的图表。

第 7 段(可获 1.24 积分)

该工具称为HistogramLogAnalyzer,您可以从Github下载源代码。 HistogramLogAnalyzer获取jHiccup的输出,并生成一对简单的图形,其示例如下所示:

hdrgraph

上图显示了在收集数据时,jHiccup线程从预期的唤醒时间开始变化。 此图可用于识别指示平台上特定事件(垃圾收集发生,IO阻止等)的重要尖峰以及运行应用程序时整体平台性能的感觉。 在这个例子中,有很多变化,但是看图表的大小只有在1到4ms的区域,这对大多数人来说并不大。

第 8 段(可获 1.63 积分)

下图显示的结果,是以百分位数表示。 此图可以用于确定平台是否能够满足您对应用程序的SLA的要求。 然后可以使用此图形中的数据来帮助调整平台和应用程序代码。

在尝试分析和纠正延迟性能问题时,对定时测试您的Java平台延时情况是一个非常有用的工具。 为什么不去试一试?

第 9 段(可获 1.01 积分)

文章评论