我會從Java的角度回答這個問題,因爲我對.NET沒有深入的瞭解。但我認爲,從這個角度來看,CLR和JVM是相似的。
讓我們從操作系統開始吧。這樣做的目的是抽象出特定於硬件的接口,併爲進程提供運行時環境。
操作系統使用設備驅動程序爲類似設備(如處理器,內存,磁盤驅動器,網卡等)提供統一接口。操作系統使用系統調用來允許用戶級代碼與這些設備進行交互。如果您使用C語言編寫代碼,則在調用「close」之前,您將調用「open」,然後「讀取」和「寫入」設備。 'ioctl'(IO控制)系統調用也用於設備控制。每個操作系統都提供一組標準的系統調用(您可以在英特爾或ARM處理器上運行Linux,但每個發行版都有相同的系統調用)。順便說一句,這也是Docker的工作原理,它使用一組標準的系統調用來使容器從一個平臺移動到另一個平臺而沒有任何問題。
該操作系統還提供了同時運行多個進程的能力。對於更新的多核心機器,這確實可以並行發生,但操作系統也使用調度在多個進程或線程之間共享CPU。通過非常快速地切換流程或線程,即使在單個處理器上,也會產生同時發生的情況。
現在我們來看看JVM,這是一個用戶級進程(從操作系統的角度來看,就像任何其他用戶應用程序一樣)。這已被設計爲抽象出CPU並從Java應用程序中運行特定的功能。 Java編譯器生成的字節碼不包含任何系統調用。如果您查看字節碼指令集(在Java虛擬機規範中定義),您會發現這些指令提供了許多熟悉的低級功能,例如加載寄存器,位操作等。另外,還有很多更高級別的指令,更具體地涉及Java;像invokestatic這樣的在類上調用靜態方法的東西,monitorenter。 monitorexit鎖定,newarray等。
JVM需要這些字節碼,並將它們從CPU和操作系統無關的形式(虛擬機的形式)轉換爲運行JVM的特定CPU架構和操作系統的指令。在某些情況下,這可能是一對一的映射(對於像位運算符這樣的東西),但通常可能更加複雜,並且涉及使用系統調用來打開文件,訪問網絡接口等.JVM還使用OS來處理由應用程序創建的線程。在Java早期的操作系統(如Windows 95)中沒有線程的概念,因此JVM必須提供它自己的實現(這被稱爲綠色線程並且執行得非常糟糕)。
總結JVM需要它正在執行的類文件的平臺中性byt代碼,並將它們轉換爲本機CPU指令和系統調用以使應用程序運行。 JVM不提供任何傳統的OS服務,它只是使用它們。
這兩個虛擬機都在底層操作系統上運行,不是嗎?您不能只將它們中的任何一個安裝在帶有空白格式化硬盤驅動器的系統上並運行任何東西。 (繼續,試試吧,我們會等的) –
我在詢問關於虛擬機的信息,而不是基於它們。虛擬機不在其上運行一些虛擬操作系統嗎? – Tim
是的,他們這樣做。您提到了Java和CLR虛擬機,並且我特別指出*這兩種虛擬機都在底層操作系統*上運行。什麼部分不明確? –