【问题标题】:Java Performance Processes vs ThreadsJava 性能进程与线程
【发布时间】:2011-12-15 18:04:33
【问题描述】:

我正在用 Java 实现一个工作池。

这本质上是一个完整的对象负载,它们将拾取数据块,处理数据,然后存储结果。由于 IO 延迟,工作线程的数量将明显多于处理器内核。

服务器专门用于此任务,我想从硬件中获得最大性能(但不,我不想在 C++ 中实现它)。

最简单的实现是拥有一个创建和监控多个工作线程的 Java 进程。另一种方法是为每个工作人员运行一个 Java 进程。

假设是四核 Linux 服务器,您预计这些解决方案中的哪一个会更高效,为什么?

您可以假设工作人员永远不需要相互交流。

【问题讨论】:

    标签: java multithreading performance process worker


    【解决方案1】:

    一个进程,多个线程 - 有几个原因。

    在作业之间进行上下文切换时,在某些处理器上,线程之间的切换比进程之间的切换成本更低。这在这种 I/O 密集型情况下尤其重要,因为工作人员多于核心。您在 I/O 阻塞之间做的工作越多,这一点就越不重要。不过,良好的缓冲将为线程进程付费。

    在同一 JVM 中的线程之间切换时,至少某些 Linux 实现(尤其是 x86)不需要刷新缓存。 See Tsuna's blog。线程之间的缓存污染将被最小化,因为它们可以共享程序缓存,执行相同的任务,并共享相同的代码副本。我们谈论的是每个开关节省 100 纳秒到几微秒的时间。如果这对您来说是小土豆,那么请继续阅读...

    根据设计,一个进程的 I/O 数据路径可能会更短。

    线程的启动和预热时间通常要短得多。操作系统不必启动一个进程,Java 不必启动另一个 JVM,类加载只完成一次,JIT 编译只完成一次,HotSpot 优化完成一次,而且更快。

    【讨论】:

    • 在同一进程中的作业之间进行上下文切换并不比在进程之间切换便宜很多——现代 CPU 上上下文切换的绝大部分成本来自于代码和数据缓存的爆破, 这两种方式都是一样的。如果一个设计有如此多的上下文切换,以至于上下文切换性能很重要,那么这个设计就会被严重破坏。
    • “在线程之间切换比在进程之间切换要便宜得多” - 请您提供一些参考/基准来支持这一点。谢谢。
    • 另一个原因是Java为您提供了线程池、执行器服务和任务队列代码来轻松处理这种情况。
    • @DavidSchwartz:操作系统进程之间的上下文切换将擦除处理器中的 VM 缓存,这将导致对页表的许多额外内存访问。这不会发生在线程之间的上下文切换中,因为地址空间不会改变。但如果你能接受,我喜欢 OS 进程方法,因为工作进程更健壮,因为一个进程中的内存或其他资源泄漏不会影响其他进程。
    【解决方案2】:

    通常,在讨论多处理(每个进程一个线程)与同一进程中的多线程时,第一种情况下的理论开销大于后者(因此理论上多处理比多处理慢线程),实际上在大多数现代操作系统上,这并不是什么大问题。但是,在 Java 上下文中讨论它时,启动一个新进程的成本要比启动一个新线程高得多。启动一个新进程意味着启动一个新的 JVM 实例,这非常昂贵,尤其是在内存方面。我建议你在同一个 JVM 中启动多个线程。

    此外,如果您说线程间通信不是问题,您可以使用Java 的Executor Service 来获得大小为2x(可用CPU 数量)的固定线程池。可用 CPU 的数量可以通过 Java 的 Runtime 类在运行时自动检测。这样,您无需任何样板代码即可获得快速简单的多线程。

    【讨论】:

      【解决方案3】:

      实际上,如果您使用多个 jvm 进程执行大规模任务,则比使用多个线程的 jvm 快得多。至少我们从来没有让一个 jvm 运行得像多个 jvm 一样快。

      我们进行了一些计算,其中每个任务使用大约 2-3GB 内存并进行一些繁重的数字运算。如果我们生成 30 个 jvm 并运行 30 个任务,它们的性能比在一个 jvm 中生成 30 个线程要好 15-20%。我们尝试调整 gc 和各种内存部分,但始终赶不上第一个变体。

      我们在不同的机器上做了这个,16 核服务器上的 14 个任务,36 核服务器上的 34 个任务等。java 中的多线程总是比多个 jvm 进程执行 worde。

      在简单的任务上可能没有任何区别,但在繁重的计算上,jvm 在线程上的性能似乎很差。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-16
        • 1970-01-01
        • 2021-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-19
        相关资源
        最近更新 更多