【发布时间】: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