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

标签 java linux

初始问题:

我有一个应用程序使用 ExecutorService 来运行 4 个固定线程池。当我使用这种架构时,应用程序在 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 指出了这一点。

最佳答案

我唯一能想到的是,这两个系统的内存设置有些不同,而且您在 Linux 领域的早期内存不足。这里有一些尝试:

  • 增加 Linux 下的内存设置(duh)。 -Xmx1G什么的
  • 将每个 future 分配给 null在你收获它之后。这可能影响不大,但可能值得帮助 GC。

    for(int i = 0; i < n; i++) {
       future[i].get();
       future[i] = null;
    }
    
  • 不要存储 Perform数组中的对象。只需提交它们,然后忘记它们。如果您仍然需要它们,请在 Future<Perform> 中归还它们完成后将它们设置为 null。
  • 最好的办法可能是不要一次提交所有作业,而是保留 100 个未完成的作业或类似的东西。转Future将数组放入列表中并收获一次 isDone()isCancelled()并且只有在列表的大小低于某个阈值时才提交给池。你需要 sleep 才能不旋转。我最近确实这样做了,所以这里有一些示例代码:http://pastebin.com/3TkkxGYT

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

关于Java:Executor Service 在 linux 上运行缓慢而不是在 Windows 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9280321/

相关文章:

java - ArrayList索引?

java - 没有水平和垂直线的 JTable

linux - gnome 终端无法正确地将输出传输到文件 bash 脚本

php - NGINX: connect() to unix:/var/run/php7.0-fpm.sock 失败(2:没有这样的文件或目录)

linux - 定时器上的管道输入

java - 是否可以使注释适用于特定类型的字段?

java - 在 Android Studio 中解析 JSON 对象

linux - 通过 SSH 和私钥连接到 MySQL

c - 在这个特定场景中,内联代码放在哪里?

java - 使用java建立app服务器和oracle数据库的连接