【问题标题】:Java Heap Multithreading OptimizationJava 堆多线程优化
【发布时间】:2013-08-21 19:48:26
【问题描述】:

我正在编写一个 Java 程序,该程序在不同的线程中同时运行许多模拟并将结果平均在一起。我想运行很多模拟,而不是同时运行,所以我想同时运行尽可能多的模拟,而不会耗尽内存并将其余的“排队”。

有没有简单的方法来确定线程使用的最大堆内存?

有没有一种简单的方法可以检查运行时使用了多少堆内存,以便我只能在内存打开时启动新线程?

PS:我是优化多线程应用程序的新手。

【问题讨论】:

  • 你考虑过使用线程池吗?

标签: java multithreading queue heap-memory


【解决方案1】:

分析您的线程以确定占用了多少堆。我知道无法以编程方式执行此操作。

使用的线程数不要超过内核数。创建新线程是一项相对昂贵的操作,创建过多线程实际上会导致您的应用程序运行更慢。如果您正在处理大量数据,或者需要非常低的延迟,那么您真的希望避免创建很多线程。

我建议调查ExecutorService。创建一个固定的线程池,与您的模拟机上的内核数相等。

编辑:

从 Java 1.4 开始,我们就提供了这个:

int cores = Runtime.getRuntime().availableProcessors();

试试这个,用cores线程创建一个固定的线程池。这将允许您的应用程序在内核不同的机器之间进行扩展。

请注意,这是逻辑内核的数量,因此使用英特尔的超线程功能,它会为每个处理器计算 2 个“内核”。不过,这是一个很好的衡量标准。

【讨论】:

  • 如果应用程序是 IO 绑定的,您可能希望使用比内核更多的线程。此外,创建新线程并没有那么昂贵。
  • 你说得对,不过线程是个重物。避免不必要的线程创建很重要。只需要为 IO 创建更多线程以帮助应用显示更具响应性。他只是在这里做模拟,显得更灵敏并不重要。
  • 更多线程可以帮助您提高带宽,而不仅仅是延迟。这在为模拟加载、记录或转储数据时很重要。但是不知道 OP 的模拟是做什么的,这是学术性的。
  • 线程数多于 # 个内核如何提高带宽?您将更慢地写入/读取数据,因此所有缓冲区将比以前更慢地填充。超小的 PDU 可能会通过,但这不是带宽,因为它的数据量相同。这是我看到的唯一优势。
  • 这是一个运行线程多于内核的用例:您有一个具有 N 个内核的服务器,通过 TCP 将巨大的数据缓冲区推送到 M 个客户端。设 1000 >= M > N。服务器有一个千兆网卡,但是下游,每个客户端有一个每秒 1 Mbit 的链接速度返回服务器。如果我们假设有大量客户端,并且服务器一次只运行 N 个线程来将该文件推送到客户端,那么完全分发文件所需的时间要比服务器运行 M 个线程的时间长得多,因为它没有足够的并发出站连接来饱和该千兆卡。
【解决方案2】:

您可以在VisualVM 中监视程序时使用单个线程运行程序,然后使用两个线程,然后使用三个线程。内存使用量和垃圾回收频率的差异可以让您了解单个线程使用了多少堆内存,以及不同线程之间共享的对象占用了多少内存。

【讨论】:

    【解决方案3】:

    这不是一项“容易”的任务,但有一些方法可以做到。 jvm 通过管理 api 公开当前的内存使用情况。您可以使用 MemoryMXBean 和 MemoryPoolMXBean 来访问当前 jvm 内存状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多