Java垃圾回收线程优先级

9

我在面试中被问到以下问题: “垃圾回收线程的默认优先级是什么?” 我知道我们不能强制执行GC或更改其优先级,但我从未听说过它的默认优先级。有人知道吗?

5个回答

8
可能面试官想要的答案是GC在低优先级的后台进程中运行。原因是运行GC很昂贵,但它通常不是关键进程,所以只有在系统有时间执行而不会中断关键任务时才应该运行它。(实时系统中存在类似的想法 - 在后台任务中执行不重要的进程,在前台执行所有关键进程 - 所有这些进程都比后台任务具有更高的优先级。)
话虽如此,如果您阅读Sun关于垃圾回收的文献,仅将GC作为低优先级线程运行并不完全正确。实际上,GC可能不仅仅是单个线程。相反,当内存不足时,GC会运行(尽管确定内存何时不足仍然可能在后台线程中完成 - 也许其他人可以澄清这一点)。
以下是一些关于GC的好链接:

我尝试使用Process Explorer进行检查,但是线程是无法识别的,所以很难确定 :) - Chris Dennett
但请看下面我的回答,以及我在最后提到的Cliff Click的讲话:事实证明,一些GC和JIT线程必须运行在高优先级,以免受到CPU饥饿的影响。 - Neil Coffey

6
我认为这个问题的正确答案是:“如果你认为你需要担心垃圾回收器的线程优先级,那么你可能做错了些什么。”
请记住,线程优先级不一定直接与进程获得的CPU时间有关。它因系统而异,在Windows上,线程优先级基本上用于确定等待运行的线程在可用的CPU上调度的顺序,以便高优先级线程可以抢占低优先级线程,假设两个线程实际上正在竞争CPU。并没有真正的规则“给低优先级的CPU更少的CPU时间”。 (值得注意的是,在Linux上,线程优先级(好值)和分配的CPU时间之间存在更直接的关系。)
对于像垃圾回收器这样的后台线程,在Windows中使用线程优先级时,更合适的解决方案可能是-也许是个悖论-给它一个高优先级,然后通过其他方式控制CPU使用比例(基本上,有意识地休眠适当比例的时间或等待适当的信号)。具体来说,高优先级适用于大部分时间都不需要执行任何操作的后台线程,但当它需要执行某些操作时,需要尽快地完成。
我实际上没有看过特定垃圾回收算法使用的线程优先级。但我的观点是,情况有些复杂,似乎奇怪地基于线程优先级做出任何关于垃圾回收器行为的假设。
那些更感兴趣线程优先级的人可能会喜欢查看一些我进行的线程优先级影响测量--尽管现在已经过去了几年,这些材料需要更新。
更新:巧合的是,昨天在YouTube上发布了Cliff Click的演讲。大约在35分钟左右,他提到了这一点,即某些JIT和GC线程需要以高优先级运行,以避免它们被饿死。

你是不是想链接到 "A JVM Does That?" https://www.youtube.com/watch?v=uL2D3qzHtqY? - Mike
哦,是的——我想我可能做了。谢谢!! - Neil Coffey

1

这是一个低优先级线程(确切的优先级不确定)。关键在于尽可能避免 GC 减慢普通线程的速度。我会说它具有低于正常的优先级 :)


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

1
在Java RTS中,垃圾回收线程的优先级可以根据需要进行调整。优先级调整(以及线程调度总体而言),在多个CPU上与仅有一个CPU时是有所区别的。
暂时假设采用多个CPU配置,因为这是目前最常见的情况。我只谈论默认调度程序,其他调度程序可能完全不同。您的线程基本上分为两类:关键和非关键优先级(您还可以有"无堆实时"线程,它们的优先级高于这两者,但由于它们不使用堆,对于GC来说几乎没有任何相关性)。垃圾回收线程通常以比这两类线程更低的优先级运行,但在需要时,可以提升到比非关键线程更高的优先级。然而,GC线程的优先级始终低于关键实时线程的优先级。
我对于"关键"和"非关键"优先级之间的界定有些含糊不清,原因是尚待调整。您可以选择哪些线程的优先级可以被GC抢占,哪些不能。意图是让关键线程获得硬实时响应,而非关键线程获得软实时响应。您需要决定/配置哪些线程属于哪个类别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接