FixedThreadPool内存泄漏

时间:2017-07-03 20:08:32

标签: java multithreading groovy memory-leaks threadpoolexecutor

我有一个Stream<String>并对其项目执行一些操作,包括处理String并将其写入文件。

拥有以下groovy代码,处理 100万个项目我遇到了 OutOfMemoryError

ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())

stream.forEach { item ->
    executorService.execute {
        handle(item)
    }
}

executorService.shutdown()
executorService.awaitTermination(1, TimeUnit.DAYS)

经过一些分析后,我发现在阻止应用程序失败之前,gc处理了Runnable任务,并且在BlockingQueue 中保持活着状态。

为什么ExecutorService将完成的Runnable保留在队列中?以及它应该如何清理?

1 个答案:

答案 0 :(得分:2)

导致内存泄漏是因为BlockingQueue填充得更快,然后ExecutorService从中提取任务。

这是因为使用forEach方法对流进行迭代非常快,但任务正在运行一段时间。

这是我申请的解决方案

def processors = Runtime.getRuntime().availableProcessors()
ExecutorService executorService = new ThreadPoolExecutor(
    processors, processors,
    0L, TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<Runnable>(1000),
    new ThreadPoolExecutor.CallerRunsPolicy()
)

这基本上只是限制了BlockingQueue的大小,并确保主线程在队列已满时将接受该作业。

感谢@JBNizet和其他人在上述评论中的帮助。