如何降低JAVA应用程序的CPU使用率?

4
在一个Linux机器(CentOS 6.5 64位)上有两个Java进程(A,B)。A使用sockets向B发送大量二进制数据。B将数据写入磁盘。每秒钟会写入50-100MB的数据。在四核处理器上,CPU几乎达到100%。之前我们运行过一个类似的应用程序,但是采用了C编写,只使用了25%的CPU。
我们进行了很多调优。我们了解到epoll存在一些错误,因此我们将JDK版本升级到了1.8。我们还进行了一些JVM调优。现在总体CPU使用率比以前低,但我们并不满意。我们认为我们可以进一步降低它。
有大量的数据写入磁盘。我们认为磁盘不是瓶颈所在,因为我们使用的是大型RAID。我们以前运行过采用更高磁盘带宽的C编写的类似应用程序,并且一切正常。
但是我们也发现了一个问题。当内核将脏数据刷新到磁盘时,CPU使用率会非常高。因此,我们增加了/proc/sys/vm/dirty_background_ratio以尽可能进行异步刷新。更改值后,似乎可以工作,但过了一段时间之后,高CPU问题又会出现。
我们能否对具有高IO带宽的Java应用程序进行更多性能调优?

可能是套接字代码的问题。没有看到它就无法确定。 - user207421
或者使用简单的流式输入/输出而不是像NIO这样的东西。 - chrylis -cautiouslyoptimistic-
如果您的CPU使用率很高,您需要找出原因并解决它。为了提高性能,我会在机器之间使用套接字,但在同一台机器上时更喜欢使用共享内存。如果您无法这样做,请让A和B在同一个进程中运行,并消除CPU负担,至少可以看看如果没有负担会发生什么。 - Peter Lawrey
我们使用条带化技术。超过12个磁盘。 - flypen
你正在使用哪种RAID级别?如果是RAID 5或6,请改用RAID 0运行测试,因为这很可能会显著提高存储性能(取决于硬件)。由于当发生脏数据刷新时出现了问题,因此您的存储性能肯定可能是问题所在。此外,增加/proc/sys/vm/dirty_background_ratio只是推迟了不可避免的刷新。相反地,尝试减少它,以希望诱导更频繁但更小的刷新操作。 - user5071535
显示剩余5条评论
1个回答

1

在你进行性能调优之前,你需要找出什么在CPU时间上占主导地位。

这是一个多方面的话题,你需要查看内核正在做什么,哪些系统调用以什么频率发出,你的访问模式是什么,文件系统和其他存储层如何影响各种文件系统操作的特性等等。

最近,Netflix提出了一种获取完整的内核/用户空间/Java堆栈的方法,这可能是一个有用的起点,但还有许多其他需要监视的事项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接