Java:Executor Service在Linux上运行缓慢,而不是在Windows上运行

时间:2012-02-14 16:17:52

标签: java linux

初步问题:

我有一个使用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();

两个操作系统都在同一台机器上运行。 JAVA版本:windows 1.6.0_22,linux打开JDK1.6.0_20

编辑:

我尝试在linux上添加-Xincgc,似乎在最初的几分钟内代码运行速度如预期的那样,之后它开始加速并迅速减速。请注意我创建的代码块在我的应用程序中运行了数十亿次,这是否表明JVM GC在不同的操作系统中表现不同?

试用后:

尝试使用4台不同的Linux机器后,看起来openJDK导致了问题。我不应该首先安装openJDK,但感谢@Alfabravo指出它。

1 个答案:

答案 0 :(得分:1)

关于我唯一能想到的是内存设置在两个系统上有所不同,而且你早先在Linux-land中耗尽了内存。这里有一些尝试:

  • 增加Linux(duh)下的内存设置。 -Xmx1G或其他
  • 收获后将每个未来分配到null。这可能影响不大,但可能值得帮助GC。

    for(int i = 0; i < n; i++) {
       future[i].get();
       future[i] = null;
    }
    
  • 不要将Perform个对象存储在数组中。只需提交它们就可以忘掉它们。如果你仍然需要它们,那么在Future<Perform>中返回它们,然后在完成它们时将它们设置为null。
  • 最好的胜利可能是不是一次性提交所有工作,而是保持100个优秀或某事。将Future数组转换为列表并获取isDone()isCancelled()的onces,并且只有在列表大小低于某个阈值时才提交到池中。你需要睡觉才能旋转。我最近这样做了,所以这里有一些示例代码:http://pastebin.com/3TkkxGYT

另一件需要考虑的事情是,如果你的Perform任务非常小,那么你可能只是测试操作系统的上下文切换而不是其他任何事情。但我不认为它会随着时间的推移而减速。