2016-12-30 93 views
1

有人能帮我理解JVM如何在可用的CPU内核之间传播线程吗?在这里,我的愿景是如何工作的,但请给我指正。JVM如何在CPU内核之间传播线程?

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

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

因此,例如OS通过在存储器中加载JVM代码和(使用上述机构)指向CPU核中的一个到它的地址开始JVM。之后,作为单独的OS进程以及其自己的虚拟内存区域执行的JVM可以启动多个线程。

所以问题是:怎么样?

不JVM使用相同的机制为OS和OS给了JVM可以发送SIPI到其他核心和指向的解决应在一个单独的线程中执行任务的时间片期间?如果是,那么如何恢复在该内核上可由OS执行的原始程序?

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

它是如何完成的?有人可以更详细地描述它吗?

+1

JVM是一个普通的进程。它(及其线程)由OS /内核管理,包括创建和调度。就像所有其他进程和线程一样。你用粗体表示的部分也没什么特别 - 这就是所有常用线程的工作方式。 – Mat

+0

,我们可以从JVM操纵哪个CPU和内核应该用于某个线程,还是完全处于OS控制之下? – user3342955

+1

这是平台特定的。如果你在编写本地代码方面很好,那么在Linux中手动调度是通过'sched_setaffinity'系统调用完成的。据我所知,标准库中没有Java包装器。还可以看一下'taskset'命令以修改亲和力来运行整个JVM。 – gudok

回答

5

操作系统默认管理和调度线程。 JVM向操作系统发出正确的调用以实现此目的,但不涉及。

不JVM使用相同的机制作为OS

JVM使用的操作系统,它根本不知道到底发生了什么。

每个进程都有自己的虚拟地址空间,并由OS再次管理。


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

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

注:在大多数情况下,使用关联性无论是)不会帮助或者b)没有帮助像你想象的那么多。

我们用它来减少大约40的抖动 - 100微秒不经常发生,但往往不足以影响我们的性能配置。如果你希望99%的ile潜伏期尽可能低,在微秒范围内,线程亲和力是必不可少的。如果100个请求中有1个需要花费1毫秒的时间,那么我就不用担心了。