4

我想了解哪些类型的操作对 CPU 负载的贡献不成比例,并对常见操作的相对成本有一个直觉。为了尽量减少泛化,请假设 Oracle 7 HotSpot JVM。

例如:

  • 构造大量对象会消耗 CPU(我知道它会消耗内存:-))吗?
  • 满足显示器成本CPU?即,如果我们有多个线程试图进入同一个同步块,阻塞的线程是否也会消耗 CPU 周期?
  • 上述操作的相对成本?例如,“新建单个对象与迭代 X 元素数组所消耗的 CPU 相同”

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

您可以推荐有关该主题的任何好读物吗?

谢谢你,

澄清

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

  • 我不是在问“为什么我的应用程序很慢”
  • 了解使用分析器将有助于识别特定应用程序中的问题,例如,GC 会占用 CPU,或者 GC 的终身代比 Eden 空间更昂贵
  • 了解大多数操作只有在大量执行时才会变得昂贵(即,如果谨慎使用,几乎没有任何操作是昂贵的)

相反,我正在寻找相对CPU 成本的指导,尤其是上述操作(让我们假设一个“网络规模”应用程序使用所有提到的相同数量的操作 - 很多)。

例如,我现在已经:

  • 长方法调用链不会显着增加 CPU 负载(因此通常可以自由地使用方法委托)
  • 抛出异常比使用条件更昂贵(因此后者通常首选用于高度性能敏感代码中的流控制)

...但是实例化新对象或满足监视器呢?这些操作中的任何一个是否会对大规模 CPU 负载(假设我不关心延迟或堆大小)产生重大(主要?)贡献者?

4

3 回答 3

2

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

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

由于发现真正的热点并不容易,您可能希望使用专门的 Java 性能分析工具来调查您的应用程序。通过这种方式,您可以了解哪些模式是 CPU 密集型的,哪些模式不是。

Java 中的另一件事是,如果您分配了大量无法快速释放的内存(无论是大块还是小块),那么垃圾收集可能会占用 CPU。使用大量字符串(例如在处理 XML 时)可能是这样的原因。

但最好的事情真的是使用分析工具。

于 2012-10-19T18:44:17.247 回答
1

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

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

2) 监控——速度较慢;挂起和等待线程不消耗CPU,切换消耗CPU很少,但比索引多

3)如果一个对象很复杂并导致创建子对象,创建一个对象可能会很慢;创建一个new Object()比线程切换稍慢一点;但可能是我错了,它是一样的;反正可比

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

于 2012-10-19T19:16:02.057 回答
1

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

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

这是一个包含有关 OpenJDK JVM 的内部信息的页面,其中列出了有关性能的信息以获取更多信息。

于 2013-03-04T11:17:40.453 回答