2016-12-30 77 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毫秒的時間,那麼我就不用擔心了。

相關問題