Oracle Hotspot JVM:通常,哪些操作特别是CPU成本高昂?

时间:2012-10-19 18:10:37

标签: java performance jvm jvm-hotspot

我想了解哪些类型的操作对CPU负载造成不成比例的影响,以及对常见操作的相对成本产生直觉。为了最小化一般化,请假设Oracle 7 HotSpot JVM。

例如:

  • 构建大量的对象会花费CPU(我明白它需要内存:-))?
  • 是否满足于监视器成本CPU?即如果我们有多个线程试图进入同一个同步块,那么被阻塞的线程也会占用CPU周期吗?
  • 以上运营的相对成本?例如,“新建一个对象的成本与迭代X元素阵列的CPU相同”

有关开发典型操作的相对CPU成本直觉的任何提示吗?

您可以推荐哪些关于这个主题的好读物?

谢谢,

澄清

感谢早期回复,但请注意我:

  • 我不是在问'为什么我的应用程序很慢'
  • 明白使用分析器可以帮助识别特定应用程序中的问题,例如,GC可能会占用CPU,或者GC的终身产生比Eden space更昂贵
  • 明白大多数操作只有在执行很多的情况下才会变得昂贵(例如,如果少量使用,操作上几乎不会昂贵)

相反,我正在寻找相对 CPU成本的指导,尤其是w.r.t.以上操作(让我们假设一个'web-scale'应用程序使用所有提到等量的操作 - 很多)。

例如我现在已经说过:

  • 长方法调用链对CPU负载没有显着贡献(所以通常可以自由地使用方法委派)
  • 抛出异常比使用条件更昂贵(因此后者通常优先用于高性能敏感代码中的流控制)

...但是为显示器实例化新对象或内容呢?这些操作中的任何一个都是重要的(显性?)贡献者的CPU负载(假设我不关心延迟或堆大小)吗?

3 个答案:

答案 0 :(得分:1)

单个操作总是很快。可测量的CPU负载操作执行数千次甚至一百万次或十亿次。因此,您需要注意各种循环和重度递归调用。

通常,由于显而易见的循环只执行了一百次,所以某些东西执行了一百万次并不明显。但它调用一个执行一百次的函数,其中包含执行一百次操作的另一个函数。这样你最终会得到一百万次运行的东西。在Web应用程序中,它会与并发请求的数量相乘。

由于要发现真正的热点并不容易,您可能希望使用特殊的Java性能分析工具来调查您的应用程序。这样你就可以了解哪些模式是CPU密集型的,哪些模式不是。

Java中的另一件事,如果你分配了大量内存(无论是少量的大块和许多小块)都无法快速发布,那么垃圾收集就会变成CPU占用。使用大量的字符串(例如,在处理XML时)可能是这样的原因。

但最好的办法是使用工具进行分析。

答案 1 :(得分:1)

我认为你写的相对CPU消耗如下:

1)数组的索引;它很快;它只是在解决

2)监视器 - 更慢;挂起和等待线程不消耗CPU,切换消耗很少的CPU,但不仅仅是索引

3)如果对象很复杂并且导致创建子对象,则创建对象可能会很慢;创建单个new Object()只比线程切换慢一点;但可能是我错了,它是一样的;无论如何可比性

4)抛出/捕捉异常非常缓慢;它比创建对象慢10-100倍

答案 2 :(得分:0)

抛出异常可能非常便宜。昂贵的部分通常只是创建异常对象,因为这会调用fillInStackTrace(),这很昂贵。如果省略这个,其余部分很快(它可以和C中的goto一样快)。

来源:https://blogs.oracle.com/jrose/entry/longjumps_considered_inexpensive

以下是page with internals about the OpenJDK JVM that lists information about performance以获取更多信息。