【问题标题】:Java Garbage Collection thread priorityJava 垃圾收集线程优先级
【发布时间】:2011-04-05 14:45:50
【问题描述】:

我在一次采访中被问到以下问题: “垃圾回收线程的默认优先级是多少?” 我知道我们不能强制 GC 或更改其优先级,尽管我从未听说过它的默认优先级。有人知道吗?

【问题讨论】:

    标签: java multithreading garbage-collection thread-priority


    【解决方案1】:

    可能面试官正在寻找的答案是 GC 处于低优先级的后台进程中。这样做的原因是运行 GC 的成本很高,但它(通常)不是关键进程,所以它应该只在系统有时间执行而不是中断关键任务时执行。 (实时系统中也存在类似的想法——在后台任务中执行不重要的进程,在前台执行所有关键进程——所有这些都将具有比后台任务更高的优先级。)

    话虽如此,如果您阅读有关垃圾收集的 Sun 文献,仅将 GC 作为低优先级线程运行是不正确的完全。实际上,GC 可能不仅仅是一个线程。相反,GC 在内存不足时运行(尽管确定内存何时不足仍然可能在后台线程中完成 - 也许其他人可以澄清这一点)。

    这里有一些很好的关于 GC 的阅读链接:

    【讨论】:

    • 我尝试使用 Process Explorer 进行检查,但是线程当然是无法识别的,所以很难分辨 :)
    • 但是请看下面我的回答和我最后提到的 Cliff Click 的演讲:事实证明,一些 GC 和 JIT 线程必须运行高优先级,这样它们才不会被 CPU 饿死。
    【解决方案2】:

    我想说这个问题的正确答案是“如果你认为你需要担心垃圾收集器的线程优先级,那么你可能做错了什么”。

    请记住,线程优先级不一定与进程获得多少 CPU 时间直接相关。它因系统而异,但在 Windows 上,线程优先级主要用于确定等待运行的线程被调度到可用 CPU 上的 ORDER,以便高优先级线程可以抢占低优先级线程,假设两个线程实际上都在竞争 CPU。没有真正的规则来“给具有较低优先级的 CPU 更少的 CPU 时间”。 (值得一提的是,在 Linux 上,线程优先级(不错的值)和分配的 CPU 时间之间存在更多直接关系。)

    按照在 Windows 中使用的线程优先级,对于像垃圾收集器这样的后台线程,一个更合适的解决方案可能(也许是自相矛盾的)给它一个高优先级,然后控制其他一些 CPU 使用的比例手段(本质上,故意睡适当的时间比例或等待适当的信号)。具体来说,高优先级适用于大部分时间不需要做任何事情的后台线程,但当它确实需要做某事时,它需要尽快做。

    我实际上没有查看特定垃圾收集算法使用的线程优先级(如果有的话)。但我的观点是,情况有些复杂,将垃圾收集器的行为基于线程优先级的任何假设似乎很奇怪。

    那些对线程优先级更感兴趣的人可能想看看我拍的一些measurements of the effect of thread priorities——诚然,几年前的现在,这个材料可以用来更新。

    更新:巧合的是,昨天在 YouTube 上发布了 talk by Cliff Click。大约 35 分钟后,他准确地提到了这一点,即某些 JIT 和 GC 线程需要运行高优先级,以免它们被饿死。

    【讨论】:

    【解决方案3】:

    它是低优先级线程(不确定确切的优先级)。这里的重点是尽可能避免 GC 减慢普通线程的速度。我会说它的优先级低于正常水平:)

    【讨论】:

      【解决方案4】:

      也许问题是针对 JVM 的实际实现。正如您在在线参考资料中所读到的,有多种方法可以实现垃圾收集器,并且它可能会因版本而异。这就是为什么每个人都告诉你不要依赖 GC 的行为。它在另一个 JVM 上的工作方式可能不同。

      【讨论】:

        【解决方案5】:

        至少在 Java RTS 中,垃圾回收线程的优先级可以根据需要进行调整。多个 CPU 的优先级调整(以及一般的线程调度)也与仅一个 CPU 有很大不同。

        目前,我将假设多 CPU 配置,因为这(到目前为止)是最常见的。我也只是在谈论默认调度程序——其他调度程序可以完全不同地做事。你的线程基本上分为两类:关键优先级和非关键优先级(你也可以有“无堆实时”线程,它们高于任何一个,但由于它们不/不能使用堆,它们与GC关系不大)。垃圾收集线程通常以低于其中任何一个的优先级运行,但在需要时/如果需要,可以提升到比非关键线程更高的优先级。不过,GC 线程的优先级始终低于关键实时线程的优先级。

        我对“关键”和“非关键”优先级之间的划分有点模糊,原因是:这是可以调整的。您可以选择哪些线程的优先级可以被 GC 抢占,哪些不能。目的是关键线程获得硬实时响应,而非关键线程获得软实时响应。由您决定/配置哪些线程属于哪个类别。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-08
          • 1970-01-01
          • 2011-03-18
          • 2011-01-26
          • 1970-01-01
          • 2011-01-06
          • 1970-01-01
          相关资源
          最近更新 更多