2009-05-29 159 views
18

我一直在研究如何編程語言的工作,其中一些有所謂的虛擬機。我知道這是另一種編程語言中編程語言的某種形式的模擬,並且它的工作方式就像一個編譯語言將如何執行,以及一個堆棧。我有沒有得到那個權利?虛擬機如何工作?

在附帶條件是我做了什麼之後,我發現很多非編譯語言允許使用「自由」類型系統的變量。在Python例如,我可以這樣寫:

x = "Hello world!" 
x = 2**1000 

字符串和大整數完全無關,並佔據不同量的內存空間,所以這怎麼能代碼即使在一個基於堆棧的環境來表示?究竟發生了什麼? x是否指向堆棧中的新位置,並且舊字符串數據未被引用?這些語言不使用堆棧嗎?如果不是,他們如何在內部表示變量?

+4

大的第一個問題! – samoz 2009-05-29 21:02:45

+0

相關問題:http://stackoverflow.com/questions/688803/how-does-a-register-based-virtual-machine-work – lothar 2009-05-29 21:18:38

回答

7

可能您的問題應該標題爲「動態語言如何工作?」。

這很簡單,它們將變量類型信息與它一起存儲在內存中。這不僅在解釋或JIT編譯語言中完成,而且還在本地編譯的語言(如Objective-C)中完成。

+0

啊哈,我明白了。但是在重新分配期間會發生什麼?如果新數據比舊數據大,那麼它放在哪裏以及舊數據是什麼? – Martin 2009-05-29 21:10:21

2

在大多數VM語言中,即使變量本身位於堆棧上,變量也可以概念化爲堆中內存的指針(或引用)。對於具有原始類型的語言(例如,Java中的int和bool),這些語言也可以存儲在堆棧中,但不能動態分配新類型。

忽略原始類型,堆棧中存在的所有變量都將其實際值存儲在堆中。因此,如果您動態地爲它們重新分配一個值,則放棄原始值(並通過一些垃圾收集算法清理內存),並將新值分配到新的內存位中。

1

許多「虛擬機如何處理像這樣或那樣的變量」的關鍵真的歸結爲元數據...存儲和更新的元信息給了虛擬機一個更好的處理方法,如何分配然後做正確的變量。

在許多情況下,這是可以真正影響性能的開銷類型。然而,現代實施等在做正確的事情方面已經走了很長的路。

至於你的具體問題 - 將變量當作香草物體/等等......歸結爲重新賦值/重新評估有關新賦值的元信息 - 這就是爲什麼x可以看上去一種方式,然後看下一種方式。

1

若要回答您的部分問題,我建議您提供一個google tech talk about python,其中有關動態語言的一些問題已得到解答;例如一個變量是什麼(它不是一個指針,也不是一個引用,但在python的情況下是一個標籤)。

2

虛擬機與語言無關。任何語言都可以在虛擬機上運行(Java虛擬機已經有數百種語言)。

虛擬機啓用了一種不同類型的「彙編語言」,它更適合編譯器。所有在虛擬機中完成的任務都可以在CPU中完成,所以將虛擬機想象成一個CPU。 (有些實際上是用硬件實現的)。

這是非常低的水平,並且在很多情況下基於堆棧 - 而不是寄存器,機器級數學都相對於相對於當前堆棧指針的位置。

使用正常的編譯語言,一步就需要很多指令。 a +可能看起來像「從相對於堆棧指針的點抓取項目到reg a,再抓入reg b。添加reg a和b。將reg a放入相對於堆棧指針的位置中。 VM用一個簡單的指令,可能是一個或兩個字節,而不是機器語言中的每個指令4或8個字節(取決於32位或64位體系結構)來執行所有這些操作(猜測)應該是指大約16或32字節的x86 1-2個字節的機器代碼。(我可能是錯的,我的最後86編碼是80286的時代。)

Microsoft使用(可能仍然使用)的虛擬機在其辦公產品,以減少代碼量。

程序爲cr吃VM代碼與創建機器語言相同,本質上只是一種不同的處理器類型。

虛擬機還可以實現與語言非常緊密相關的自己的安全性,錯誤恢復和內存機制。

這裏的一些描述是摘要和內存。如果你想自己探索字節碼的定義,它還挺好玩:

http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc.html