為什麼Java裡面的JVM就叫虛擬機器,Python的叫直譯器呢?講道理,這個格調聽著有差一條街的
一個.py檔案執行的生命週期
1)python.exe直譯器先把.py檔案中的code編譯為位元組碼。
2)位元組碼檔案再被python.exe執行:這個時候直譯器接收到的位元組碼檔案都是PyCodeObject為單位的,一個一個執行。什麼是PyCodeObject,舉個例子好比,你有一個孩子(物件),你的孩子的樂園就是家+你家花園(作用域),那麼這就是一個PyCodeObject物件,直譯器就以這樣的物件為單位來劃分。但是如果有一段程式碼表示的是:你的孩子去別人家的後花園玩耍,那麼一個PyCodeObject就不夠描述這一件事情了,所以就必須在懟一個PyCodeObject出來來描述這樣的程式碼,所以就成了翻譯兩個PyCodeObject對物件。 PyCodeObject中裝的什麼?裝的不是空氣,也不是充氣的,裝的是所有的靜態變數的資訊和位元組碼,不包括環境(PyFrameObject),我之前的例子只是想說明白PyCodeObject劃分的原則,就是一個物件不夠描述一件事,所以就會劃分另一個物件。這些PyCodeObject,Base在PyFrameObject上執行,每一個PyFrameObject物件中都維護了一個PyCodeObject表示每一個PyFrameObject的動態記憶體空間和原始碼的一段Code相對應。所以直譯器會根據上下文(PyFrameObject)來執行
位元組碼
位元組碼在直譯器中的形式為PyCodeObject,在磁碟中表示為.pyc檔案
執行緒和程式的模擬
作業系統裡面最重要的兩個概念是程式和執行緒,Python中使用的是PyInterpreterState和PyThreadState來表示的,直譯器啟動後會執行一些Initsettings,最後進入PyEvalFrame函式,它的作用就是不斷的讀取PyCodeObject物件
.pyc檔案
不是所有的.pyc檔案都會產生.pyc檔案,python直譯器預設會重用的程式碼才具有保留價值,什麼叫重用,當時是被Import了,或者你自己使用python內建的complie方法來編譯.pyc
Python記憶體管理
為了提高效率,python引入了記憶體池機制,將不用的存放在記憶體池而不是返回給OS,Pymalloc用於管理小塊的記憶體申請和釋放(物件小於256k),大於256的大塊記憶體由底層的malloc、free等函式記憶體管理和分配的函式進行操作
最後,題目的問題:那就來對比下Java和Python
·首先Java是靜態語言內部的編譯器進行翻譯JavaCode為位元組碼檔案,然後由執行器執行位元組碼檔案。而Python的編譯器,美其名曰打工皇帝,身兼數職,一遍翻譯一邊執行,這叫動態語言,並且居然翻譯成位元組碼Python的位元組碼都比Java的短,雖然是打工皇帝但是一個人的力量還是不如JVM分工的快。不過他倆都是跨平臺的就是因為虛擬機器的機制,就像平頭插座插不了三角頭,但是裝個轉換器啦。使用轉換器的原因就是要提供一個和宿主平臺無關的編譯環境,所以java不是解釋語言也不是編譯語言,它屬於二合一,但是python作為動態語言也提供了各種優化機制保留.pyc檔案等等,所以現在編譯語言跟解釋語言的界限越來越不明顯,這麼來看她確實該叫直譯器,翻譯加執行,好比我給你說這句話不是說而已還要你懂....Anyway雖然有些生搬硬套了但是,講道理python虛擬機器多學學也不錯,知道這些面試感覺足夠了~