初始问题:
我有一个应用程序,使用ExecutorService来运行4 fixedThreadPool。当我使用这个架构时,应用程序在Windows系统上运行得更快,这是一个单线程架构。但是,当我在linux中运行ExecutorService架构时,我的应用程序的性能比单线程应用程序更差。
两台机器上的CPU和其他硬件是相同的。我甚至在不同的机器上进行了尝试,得到了相同的结果。我甚至尝试将fixedThreadPool限制为3或2,但仍然获得了较慢的性能。我遗漏的导致linux机器运行缓慢的变量是什么?
ExecutorService execSvc =
Executors.newFixedThreadPool(NUMBER_OF_PROCESSORS);
Perform perform[] = new Perform[n];
Future<?>[] future = new Future<?>[n];
for(int i=0;i<n;i++)
future = execSvc.submit(perform[i]);
for(int i=0;i<n;i++)
//To wait until all done
future[i].get();
这两个操作系统都在同一台机器上运行。JDK1.6.0_20版本: windows 1.6.0_22、linux Open JAVA
编辑:
我尝试在linux上添加-Xincgc,在开始的几分钟内,代码运行的速度和预期的一样快,之后它开始变得越来越快,速度越来越慢。请注意,我创建的代码块在我的应用程序中运行了无数次,这是否表明JVM在不同的操作系统上表现不同?
试验结束后:
在尝试了4台不同的linux机器后,似乎是openJDK导致了问题。我一开始就不应该安装openJDK,但感谢@Alfabravo指出了这一点。
发布于 2012-02-14 17:58:54
我能想到的唯一一件事就是在两个系统上的内存设置是不同的,并且你在Linux-land中的内存早些时候已经用完了。下面是一些值得尝试的事情:
-Xmx1G
或somethingnull
。这可能效果不大,但可能值得帮助GC解决问题。for(int = 0;i< n;i++) { futurei.get();futurei = null;}
Perform
对象存储在数组中。只需提交它们,然后忘记它们。如果你仍然需要它们,那么在Future<Perform>
中返回它们,然后在你完成它们时将它们设置为null。
Future
数组转换为列表,并获取isDone()
或isCancelled()
的一次,只有当列表的大小低于某个阈值时才提交到池中。你需要睡一觉才能不旋转。我最近确实这样做了,所以这里有一些示例代码:http://pastebin.com/3TkkxGYT另一件要考虑的事情是,如果您的Perform
任务非常小,那么您可能只是在测试操作系统的上下文切换,而不是其他任何东西。但我不认为它会随着时间的推移而放缓。
https://stackoverflow.com/questions/9280321
复制相似问题