深入java虛擬機(jī)1-4章, all in sandbox(1)關(guān)鍵字: 09年讀書(shū)如果你尚未閱讀深入java虛擬機(jī),推薦你先閱讀深入理解計(jì)算機(jī)系統(tǒng)。 如果你已經(jīng)閱讀過(guò)深入理解計(jì)算機(jī)系統(tǒng),推薦你閱讀深入java虛擬機(jī)。 如果這兩本書(shū)你都閱讀過(guò)或者都在閱讀,我就不知道說(shuō)什么好了。
java虛擬機(jī)(jvm)是建立于一個(gè)本地系統(tǒng)之上沙箱之中。 這個(gè)基礎(chǔ)天生便決定了java的平臺(tái)平臺(tái)無(wú)關(guān)性。 我們所編寫(xiě)的java程序調(diào)用java api,由java api調(diào)用 本地方法(動(dòng)態(tài)庫(kù))操作本地系統(tǒng)。 由此帶來(lái)了內(nèi)存管理,安全管理等一系列問(wèn)題。
java的內(nèi)存管理
java api沒(méi)有通過(guò)提供強(qiáng)制裝換指針或者通過(guò)指針運(yùn)算直接訪問(wèn)內(nèi)存的方法。 java使用自動(dòng)垃圾回收機(jī)制,通過(guò)停止對(duì)一個(gè)java對(duì)象的引用來(lái)促使垃圾收集器自動(dòng)回收這個(gè)對(duì)象所占據(jù)的內(nèi)存。 java使用數(shù)組邊界檢查而防止出現(xiàn)因此而引發(fā)的內(nèi)存沖突。
java的平臺(tái)無(wú)關(guān)性 java虛擬機(jī)規(guī)范規(guī)定了java虛擬機(jī)中基礎(chǔ)類(lèi)型的規(guī)格,因此通過(guò)使用不同平臺(tái)的java虛擬機(jī),而跨越不同的系統(tǒng)平臺(tái)實(shí)現(xiàn)。 因此編寫(xiě)java程序一個(gè)很重要的原則就是不要直接或者間接調(diào)用不屬于java api的本地方法。
對(duì)java虛擬機(jī)的依賴(lài) 編寫(xiě)平臺(tái)獨(dú)立的java程序時(shí)候,要遵循兩條原則: 1 不要依賴(lài)及時(shí)終結(jié)來(lái)達(dá)到程序的正確性 。 不同的java虛擬機(jī)有不同的垃圾回收機(jī)制的實(shí)現(xiàn)。 2 不要依賴(lài)線(xiàn)程的優(yōu)先級(jí)來(lái)達(dá)到程序的正確性。 不同的java虛擬機(jī)有不同的線(xiàn)程優(yōu)先級(jí)的實(shí)現(xiàn)。為了保障多線(xiàn)程java程序的平臺(tái)無(wú)關(guān)性,必須依賴(lài)同步機(jī)制而不是優(yōu)先級(jí)機(jī)制來(lái)協(xié)調(diào)線(xiàn)程。
java的安全管理機(jī)制
java沙箱機(jī)制是java程序運(yùn)行在一個(gè)受限的內(nèi)存空間。 例如某個(gè)java程序產(chǎn)生了outofmemory的異常,只會(huì)導(dǎo)致這個(gè)java程序終止。并不會(huì)導(dǎo)致其他java程序或者其他應(yīng)用程序終止。
java沙箱由以下幾部分組成: 類(lèi)裝載器體系結(jié)構(gòu)class文件檢驗(yàn)器內(nèi)置于java虛擬機(jī)(及語(yǔ)言)的安全特性安全管理器及java api
類(lèi)裝載器體系結(jié)構(gòu)
類(lèi)裝載器體系結(jié)構(gòu)在三個(gè)方面對(duì)java沙箱起作用: 1.防止惡意代碼去干涉善意代碼。 2.守護(hù)了被信任的類(lèi)庫(kù)的邊界 3.將代碼歸入了保護(hù)域,該保護(hù)域確定了代碼可以進(jìn)行哪些操作。 類(lèi)裝載器通過(guò)為不同的類(lèi)提供不同的類(lèi)裝載命名空間來(lái)防止惡意代碼干涉善意代碼。相同命名空間內(nèi)的類(lèi)可以相互訪問(wèn)而不同命名空間內(nèi)的類(lèi)彼此并不可視因而也無(wú)法相互訪問(wèn)。 類(lèi)裝載器守護(hù)被信任的類(lèi)庫(kù)邊界通過(guò)使用不同的類(lèi)裝載器裝載不同的包而實(shí)現(xiàn)的。
class文件校驗(yàn)器
class文件校驗(yàn)器用來(lái)檢驗(yàn)class文件的字節(jié)碼。防止阻止方法內(nèi)的跳轉(zhuǎn)指令跳到方法之外。 class文件會(huì)對(duì)一個(gè)class文件的字節(jié)碼序列進(jìn)行四次掃描
1 class文件的結(jié)構(gòu)檢查 java的class文件是以0xCAFEBABE開(kāi)頭作為文件類(lèi)型標(biāo)識(shí)的。主要檢查class文件的完整性,保障這個(gè)字節(jié)序列遵從class文件的文件格式,這樣才能編譯成在方法區(qū)的內(nèi)部數(shù)據(jù)結(jié)構(gòu)。第2,3,4次掃描是在方法區(qū)內(nèi)進(jìn)行的。
2 類(lèi)型數(shù)據(jù)的語(yǔ)言檢查 檢驗(yàn)器檢查每個(gè)組成部分,確認(rèn)其是否是所屬類(lèi)型的實(shí)例,它們的結(jié)構(gòu)是否正確。其目的是為了確認(rèn)每個(gè)方法描述符都是符合特定格式,格式正確的字符串。還會(huì)檢查這個(gè)類(lèi)本身是否符合特定的條件??傊?,檢驗(yàn)器會(huì)檢驗(yàn)有編譯器產(chǎn)生的class文件是否遵守一些java語(yǔ)言在編譯時(shí)必須遵守的強(qiáng)制規(guī)則。
3字節(jié)碼驗(yàn)證 字節(jié)碼流代表了java的方法,它是由被稱(chēng)為操作碼的單字節(jié)指令組成的序列。每個(gè)操作碼后面都跟著一個(gè)或者多個(gè)操作數(shù)(這一點(diǎn)很類(lèi)似匯編語(yǔ)言的指令)。操作數(shù)用于在java虛擬機(jī)執(zhí)行操作碼指令時(shí)提供所需的額外的數(shù)據(jù)。執(zhí)行字節(jié)碼時(shí),依序執(zhí)行每個(gè)操作碼,這樣就在java虛擬機(jī)內(nèi)部形成了執(zhí)行的線(xiàn)程。每個(gè)線(xiàn)程被授予自己的java棧。這個(gè)棧就是由不同的棧幀組成的。每一個(gè)方法的調(diào)用將獲得一個(gè)自己的棧幀(其實(shí)就是一個(gè)內(nèi)存片段),其中存儲(chǔ)著局部變量和計(jì)算的中間結(jié)果。在棧幀中用于存儲(chǔ)方法的中間結(jié)果的部分被稱(chēng)為該方法的操作數(shù)棧。操作碼和它的(可選)操作數(shù)可能指存儲(chǔ)在操作數(shù)棧中的數(shù)據(jù)或者存儲(chǔ)在方法棧幀中的局部變量中的數(shù)據(jù)。這樣,在執(zhí)行一個(gè)操作碼時(shí),除了可以使用緊隨其后的操作數(shù),虛擬機(jī)還可以使用操作數(shù)棧中的數(shù)據(jù),或存儲(chǔ)在方法棧幀中的局部變量中的數(shù)據(jù),或兩者都使用。 字節(jié)碼驗(yàn)證要校驗(yàn)直接碼流符合java的操作碼和操作數(shù)能夠被java虛擬機(jī)安全地執(zhí)行。
4符號(hào)引用的驗(yàn)證 java虛擬機(jī)將追蹤直接碼流中的符號(hào)引用,并且確保符號(hào)應(yīng)用的資源可用。如果該資源不可用并不立即拋出noclassdeffounderror錯(cuò)誤,而是在運(yùn)行時(shí),這個(gè)類(lèi)被首次引用時(shí)才拋出。 動(dòng)態(tài)連接是將一個(gè)符號(hào)引用解析為直接引用的過(guò)程。當(dāng)java虛擬機(jī)執(zhí)行字節(jié)碼時(shí),如果遇到一個(gè)操作碼,這個(gè)操作碼第一次使用一個(gè)指向另一個(gè)類(lèi)的引用,那么java虛擬機(jī)就要解析這個(gè)引用。 1)查找被引用的類(lèi),如果必要的話(huà)就裝載它。 2)將符號(hào)引用替換為直接引用,例如一個(gè)指向一個(gè)類(lèi),方法或者字段的指針或者偏移量。
|
|