【问题标题】:Java needed memory for new threadJava 新线程需要内存
【发布时间】:2014-10-31 15:21:51
【问题描述】:

我有一个大量创建线程的应用程序。结果我得到一个 OutOfMemoryError。我的想法是等到有足够的可用空间来创建下一个Thread。但是因此我需要知道创建一个线程需要多少内存,以及这个内存量是否可用。有没有办法获得线程所需的内存量?以及如何确定此内存量是否可用?

我已经尝试过的:

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

【问题讨论】:

  • 我不是这里的专家,但我觉得你在比较苹果和橘子,这行:.maxMemory() - untime.getRuntime().totalMemory(),maxMemory 和 totalMemory 对我来说听起来不同
  • 为什么要创建大量线程?
  • @Coffee 这应该是 JVM 可以分配的内存,当我只使用 freeMemory() 时,它会在创建第一个线程之前阻塞。
  • 一个“大量创建线程”的应用程序对我来说听起来有点吓人。如您所见,创建线程的成本很高,这就是存在线程池的原因。您正在创建多少个线程?如果您正在创建如此多的线程,那么您会造成内存压力,这是一个严重的问题。我建议您退后一步,重新考虑您的解决方案。 《Java Concurrency in Practice》一书在这里是一个很好的资源。
  • @DavidSchwartz,当线程刚开始流行时,多处理器计算机在大学研究部门之外并不存在。发明线程是为了组织必须等待许多不同异步输入的程序(尤其是实时嵌入式程序)的一种方式。程序不会有一个大的事件循环来轮询每个不同的可能输入,而是有一个线程来等待每个不同的输入源。

标签: java multithreading out-of-memory


【解决方案1】:

不,您去删除此代码并改用ThreadPool。您尝试做的事情非常困难,您应该使用更高的抽象来执行多线程,否则您根本不这样做。

Check out Executors,目前是更高的抽象。 如果您的任务受计算限制,那么 Java 7 中的 ForkJoin 是您的朋友,只要您知道如何将问题递归地划分为子问题,您就不必担心池的大小。

【讨论】:

  • 您的解决方案有效,但我仍然不知道我可以创建多少线程。 Executors.newFixedThreadPool() 询问我的最大线程数,但这正是我不知道的。
  • @kaetzacoatl 介于 cpu 核心数量和两倍之间,更多并且性能不必要地下降。如果您整天有大量线程在等待,请使用异步框架。
【解决方案2】:

关于该问题的信息不足,无法提出最佳解决方案。

通常,当您进行昂贵的 I/O 操作时,您可能需要创建比实际 CPU 内核更多的线程。从links 变量来看,这可能是其中一种情况,但正如其他人建议的那样,创建太多线程通常表明设计不好。它甚至可能使您的系统耗尽可用资源。

即使通过网络,您的带宽也是固定的,因此除非您可以直接访问互联网骨干网,否则您不太可能获得任何性能优势,因为大多数网站都应该以高速响应。

话虽如此,即使您减慢了线程创建的速度,您也无法控制线程将消耗多少内存以及何时消耗。也就是说,您的所有线程可能会同时开始下载数据,即使您不创建任何新线程,您仍然会耗尽内存。

最后,请遵循其他用户的建议:

  • 使用ExecutorService
  • 阅读更多关于线程的信息(Java 并发在实践中是一个很好的来源)
  • 想想为什么要创建这么多线程?为什么你期望你所做的一切都会更快?

PS。如果您在问题中包含为什么需要创建这么多线程也会有所帮助

【讨论】:

    猜你喜欢
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 2016-12-09
    • 2021-07-08
    • 2012-02-17
    • 2012-02-21
    相关资源
    最近更新 更多