我有一个大规模创建线程的应用程序。结果我得到 OutOfMemoryError 。我的想法是等到有足够的可用空间来创建下一个线程。但是因此我需要知道创建一个线程需要多少内存以及这个内存是否可用。有没有办法获得线程需要的内存量?我如何确定这个内存量是否可用?
我已经尝试过的事情:
for (int i = 0; i < links.size(); i++) {
while(Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory() +
Runtime.getRuntime().freeMemory() < MEMORY_THRESHOLD) {
synchronized (lock) {
lock.wait(10);
}
}
Thread t = new Thread(new Task(links.get(i)));
t.setDaemon(true);
t.start();
}
但即使我使用100MB作为阈值,我也会得到 OutOfMemoryError 。
答案 0 :(得分:6)
不,您去删除此代码并使用ThreadPool
代替。你想要做的事情是相当困难的,你应该使用更高的抽象来做多线程,或者你根本不做。
Check out执行者,目前他们是更高的抽象。
如果您的任务是计算绑定的,那么Java 7中的ForkJoin
是您的朋友,只要您知道如何将问题递归地划分为子问题,您就不必担心池大小。
答案 1 :(得分:1)
关于该问题的信息不足以提出最佳解决方案。
通常,当您进行昂贵的I / O操作时,可能需要创建比实际CPU内核多得多的线程。从links
变量判断,这可能是其中一种情况,但正如其他人建议创建太多线程通常表明设计不好。它甚至可能使您的系统耗尽可用资源。
即使通过网络,您的带宽也是固定的,因此除非您可以直接访问互联网骨干网,否则您不太可能获得任何性能优势,因为大多数网站都应该高速响应。
话虽如此,即使您减慢了线程创建速度,也无法控制线程将消耗多少内存以及在什么时间消耗。即你所有的线程可能会同时开始下载数据,即使你没有创建任何新的线程,你仍然会耗尽内存。
总之,请按照其他用户的建议:
ExecutorService
PS。如果您包含为什么需要在问题中创建这么多线程
,这也会有所帮助