【问题标题】:Execution in FixedThreadPool gets slower as time goes by随着时间的推移,FixedThreadPool 中的执行变得更慢
【发布时间】:2016-04-25 14:44:19
【问题描述】:

我有大约 100000 个任务需要完成,我知道它们是 CPU 密集型的,但只需要很短的执行时间(当 CPU 足够快时)。

我用ExecutorService executor = Executors.newFixedThreadPool(8);

我选择 8 是因为我的 CPU 有 8 个内核。

然后为了处理我的任务,我遍历所有任务:

for(Task task : tasks) {
     executor.submit(new Runnable() {
     // 1. Text analyzing
     // 2. Add result to a LinkedBlockingQueue
     }
}

我观察到,对于最初的几千个任务,它确实很快。但是话说回来,处理完10k个任务后,速度就变慢了,越来越慢……

我试图理解但无法弄清楚为什么它会逐渐变慢。因为当任务完成时,资源也将被释放。所以我预计处理速度应该是稳定的。

然后我发现问题可能属于我用来存储任务结果的 LinkedBlockingQueue。但似乎 LinkedBlockingQueue 为插入提供了良好的性能。

有人可以给我一些提示或建议,在这种情况下我可能会做错什么吗?

谢谢。

【问题讨论】:

  • 我不认为所有内核 (8) 都会免费。即后台服务,操作系统系统也使用它们。尝试减少池,即 6
  • 最有可能的减速是队列备份,而不是执行器本身。
  • 快速找出增加堆的问题的方法。如果它的移动速度超过您的数据问题。
  • 可能值得看看 VM 内部发生了什么,看看是否有任何内存泄漏。 VisualVM 是免费的,并且足以胜任这类事情:visualvm.java.net
  • 是的,您需要检查堆/GC 活动

标签: java multithreading collections


【解决方案1】:

问题属于LinkedBlockingQueue的性能下降。在我的例子中,生产者在向队列中添加数据时效率更高,而消费者处理速度太慢。

Java performance problem with LinkedBlockingQueue

【讨论】:

  • 请注意,Queue 不是性能问题。退出队列是一个问题。 LinkedBlockiingQueue 需要的东西会很快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-04
  • 2018-09-10
  • 2017-11-02
相关资源
最近更新 更多