我想了解哪些类型的操作对CPU负载造成不成比例的影响,以及对常见操作的相对成本产生直觉。为了最小化一般化,请假设Oracle 7 HotSpot JVM。
例如:
有关开发典型操作的相对CPU成本直觉的任何提示吗?
您可以推荐哪些关于这个主题的好读物?
谢谢,
澄清
感谢早期回复,但请注意我:
相反,我正在寻找相对 CPU成本的指导,尤其是w.r.t.以上操作(让我们假设一个'web-scale'应用程序使用所有提到等量的操作 - 很多)。
例如我现在已经说过:
...但是为显示器实例化新对象或内容呢?这些操作中的任何一个都是重要的(显性?)贡献者的CPU负载(假设我不关心延迟或堆大小)吗?
答案 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以获取更多信息。