版權聲明: 本文由 一隻博客 發表於 bloghome博客程序員
看到Stackoverflow上有個問題在討論Java和Python的對比,其中就有人問答爲啥Java的運行環境被稱之爲JVM,而Python的只能叫作Interpreter。緩存
這個問題估計想過的人很少,先找維基百科看一下虛擬機的定義。編程語言
虛擬機的定義有2個,一種是相似Vmware的系統虛擬機,另外一種是虛擬機稱之爲程序虛擬機,諸如JVM,CLR就是最多見到的虛擬機。ide
程序虛擬機也稱做託管運行時環境,運行這個虛擬機時,就比如普通的OS中的一個進程。當這個進程啓動時,虛擬機啓動,當進程銷燬時,虛擬機銷燬。使用虛擬機的目的就是提供一個和平臺無關的編程環境。工具
JVM中的執行引擎只能處理編譯後的Java字節碼,字節碼處理引擎其實包含一個字節碼解釋器和一個JIT編譯器(和.net的CLR中JIT差異很大),解釋器逐條的執行字節碼指令,速度稍慢。JIT編譯器則會將熱點代碼編譯緩存起來,所以執行速度加快。性能
解釋器的概念比較簡單,它能夠將代碼翻譯,並運行,不須要通過編譯,JVM中的解釋器正式這樣的,JVM中解釋的就是字節碼。解釋器運行程序的方法有3種:spa
直接運行高級編程語言(如Shell內置的解釋器).net
轉換高級編程語言碼到一些有效率的字節碼(Bytecode),並運行這些字節碼翻譯
以解釋器包含的編譯器對高級語言編譯,並指示處理器運行編譯後的程序(例如:JIT)
其中Python的解釋器就是屬於第二種,Python代碼在首次運行時,它會將Python代碼編譯成字節碼,若是能夠的話,它會將這個字節碼保存到.pyc文件中,這樣下次啓動的時候就不會再編譯這些代碼而是直接解釋運行字節碼。事實上,這種機制正在模糊解釋器和編譯器之間的界限,或者說是模糊瞭解釋型語言和編譯型語言的界限。
經過JVM和解釋器的概念澄清,彷佛仍是不明白爲啥JVM就被稱爲虛擬機,JVM中有運行的是字節碼,它可能直接被解釋執行,也可能被再次編譯成目標語言,Python中的解釋器也會先預編譯Python代碼爲字節碼,再解釋執行。那麼到底有啥區別?
不少人蔘與了討論,分別從不一樣的角度去闡述區別。
有人認爲虛擬機是和語言無關的,JVM爲例,除了Java以外,Scala,Clojure,甚至Python藉助於Jython工具,也能夠運行在JVM上,而沒據說什麼語言能有Python解釋器解釋執行,除了Python。
也有人從語言的類型上,Java爲靜態類型的語言,而Python爲動態語言。這使得Java字節碼既能夠被解釋執行也能夠被編譯成機器指令再執行。而Python則複雜多了,它雖然讓程序員能夠不去關注變量的類型,但解釋器不得不去推斷數據類型,這必定程度上影響性能。
還有觀點認爲解釋器是一個歷史遺留術語,現代語言中虛擬機和解釋器的分界已經很模糊甚至不存在。
事實上,筆者在《Learning Python》一書中,看到把做者把Python的解釋器稱爲PVM,基於這個事實來說,本人更認同的是解釋器和虛擬機的區別正在愈來愈小,已是我中有你,你中有個人地步。獨立的分割來看,可能還能區分這幾步是解釋器行爲,這幾步是虛擬機的行爲,可是做爲一個總體來看,二者的區別確實沒那麼明顯。