【发布时间】:2017-12-07 04:10:15
【问题描述】:
我有一个Stream<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)
经过一些分析,我发现 Runnable 任务不是由 gc 处理的,而是 在 BlockingQueue 中保持活动状态,直到应用程序失败。
为什么 ExecutorService 将完成的 Runnable 保留在队列中?以及应该如何清理?
【问题讨论】:
-
它没有。你的诊断是错误的。队列包含在执行之前等待的任务。
-
这听起来不太可能——为了让队列中的项目执行它,它必须被删除。因此,如果他们留在队列中,他们就不会真正被执行。
-
@AndyTurner 的意思是我应该尝试减少队列大小?在那种情况下会发生什么?
-
Runnables 几乎没有任何状态,创建 100 万个 Runnables 不会消耗太多内存。你需要弄清楚到底是什么吃掉了那段记忆。 handle() 有什么作用?
-
您可以使用有界队列,并使用docs.oracle.com/javase/8/docs/api/java/util/concurrent/…。但是,如果您发布代码并准确地解释它应该做什么,那么提供帮助会容易得多。
标签: java multithreading groovy memory-leaks threadpoolexecutor