我有一个服务,它调用数据库并对每个结果执行回调。
ExecutorService service = Executors.newFixedThreadPool(10);
service.exectute(runnable(segmentID, callback)); // database is segmented
Runnable是:
call database - collect all the rows for the segment keep in memory
perform callback(segment);
现在问题是我得到了数据库返回的大行,我的理解是执行者服务将在I / O空闲时调度线程。所以我进入了记忆之外。
有没有办法限制一次只运行10个线程并且没有执行器服务调度?
出于某种原因,我必须将段中的所有行保留在内存中。 如何通过这样做来阻止去OOM。 Executor是否为此服务newFixedThreadPool解决方案?
如果我错过了什么,请告诉我。
谢谢
答案 0 :(得分:1)
您必须使用固定的线程池。有一条规则是你应该只生成N个线程,其中N应该与CPU中核心数量的数量级相同。关于N的大小存在争议,您可以阅读更多关于它的信息here。对于普通CPU,我们可以说4,8,16个线程。
但即使你在集群中运行你的程序,我认为你不是,你不能只从数据库中获取20k行并假装产生20k线程。如果这样做,您的应用程序的性能将会降低大量时间,因为大多数CPU周期将在上下文切换中消耗。
现在即使使用固定的线程池,如果获取的数据同时存储在内存中,也可能会遇到OOM异常。我认为唯一的解决方案是获取较小的数据块,或者在下载文件时将数据写入文件。