版權聲明: 本文由 一隻部落格 發表于 bloghome部落格 文章連結: https://www.bloghome.com.cn/user/cnn237111
看到stackoverflow上有個問題在讨論java和python的對比,其中就有人問答為啥java的運作環境被稱之為jvm,而python的隻能叫做interpreter。
這個問題估計想過的人不多,先找維基百科看一下虛拟機的定義。
虛拟機的定義有2個,一種是類似vmware的系統虛拟機,另一種是虛拟機稱之為程式虛拟機,諸如jvm,clr就是最常見到的虛拟機。
程式虛拟機也稱作托管運作時環境,運作這個虛拟機時,就好比普通的os中的一個程序。當這個程序啟動時,虛拟機啟動,當程序銷毀時,虛拟機銷毀。使用虛拟機的目的就是提供一個和平台無關的程式設計環境。
jvm中的執行引擎隻能處理編譯後的java位元組碼,位元組碼處理引擎其實包含一個位元組碼解釋器和一個jit編譯器(和.net的clr中jit差别很大),解釋器逐條的執行位元組碼指令,速度稍慢。jit編譯器則會将熱點代碼編譯緩存起來,是以執行速度加快。
解釋器的概念比較簡單,它可以将代碼翻譯,并運作,不需要經過編譯,jvm中的解釋器正式這樣的,jvm中解釋的就是位元組碼。解釋器運作程式的方法有3種:
直接運作進階程式設計語言(如shell内置的解釋器)
轉換進階程式設計語言碼到一些有效率的位元組碼(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,基于這個事實來講,本人更認同的是解釋器和虛拟機的差別正在越來越小,已經是我中有你,你中有我的地步。獨立的分割來看,可能還能區分這幾步是解釋器行為,這幾步是虛拟機的行為,但是作為一個整體來看,兩者的差別确實沒那麼明顯。