JVM如何在CPU内核之间传播线程?

时间:2016-12-30 10:33:01

标签: java multithreading jvm cpu-cores

有人可以帮我理解JVM如何在可用的CPU核心之间传播线程吗?在这里,我的视野如何发挥作用,但请纠正我。

所以从开始:当计算机启动时,引导线程(通常在处理器0中的核0中的线程0)开始从地址0xfffffff0获取代码。所有其余的CPU /内核都处于特殊的睡眠状态,称为Wait-for-SIPI(WFS)。

然后在加载OS之后,它开始管理进程并在CPU /内核之间调度它们,通过高级可编程中断控制器(APIC)发送特殊的处理器间中断(IPI),称为SIPI(启动IPI)到每个线程在WFS。 SIPI包含该线程应该从该地址开始获取代码的地址。

因此,例如OS通过在内存中加载JVM代码并将其中一个CPU内核指向其地址(使用上述机制)来启动JVM。之后,作为具有自己的虚拟内存区域的单独OS进程执行的JVM可以启动多个线程。

所以问题是:如何?

JVM是否使用与OS相同的机制,并且在操作系统提供给JVM的时间片中,可以将SIPI发送到其他核心并指向应该在单独线程中执行的任务的地址?如果是,那么如何恢复OS可以在该核心上执行的原始程序?

假设视觉不正确,假设涉及其他CPU /核心的任务应通过OS进行管理。过度我们可以中断在其他核心上并行运行的某些OS进程的执行。因此,如果JVM想要在其他CPU /核心上启动新线程,则会进行一些OS调用并将要执行的任务的地址发送到OS。 OS计划执行与其他程序一样,但执行应该在同一进程中执行,以便能够访问与其余JVM线程相同的地址空间。

怎么做?有人可以更详细地描述一下吗?

1 个答案:

答案 0 :(得分:5)

操作系统默认管理和调度线程。 JVM会对操作系统进行正确调用以实现此目的,但不会参与其中。

  

JVM是否使用与OS相同的机制

JVM使用操作系统,它不知道实际发生了什么。

每个进程都有自己的虚拟地址空间,同样由操作系统管理。

我有一个库,它使用JNA在Linux和Windows上包装setaffinity。您需要这样做,因为线程调度由OS而不是JVM控制。

https://github.com/OpenHFT/Java-Thread-Affinity

注意:在大多数情况下,使用亲和力a)没有帮助或b)没有你想象的那么多。

我们使用它来减少大约40到100微秒的抖动,这种情况并不经常发生,但往往足以影响我们的性能。如果您希望99%的ile延迟尽可能低,则在微秒范围内,线程亲和力至关重要。如果100个请求中有1个可以延长1毫秒,那我就不用了。