那天,電腦里的兩個(gè)家伙吵起來了···
某天周末,CPU和JVM聊了起來···

小兄弟,最近聽說你風(fēng)頭很猛啊
大哥見笑了,豈敢豈敢


豈敢?我看你敢的很嘛,自己搞了一套虛擬機(jī),都快把我架空了
大哥你看你說的,我就是一Java虛擬機(jī),最終還得把代碼指令發(fā)給您來執(zhí)行。根本離不開你,怎么會(huì)架空你呢


我倒是很好奇,既然最終還是得靠我來執(zhí)行指令,那你存在的意義又是什么呢?
這您就有所不知了。我作為中間商,為程序們提供了最優(yōu)質(zhì)便捷的服務(wù),要是讓他們直接跟你打交道,那還得了解你的指令集,你的I/O方式、你的內(nèi)存管理方式,可麻煩了。


別蒙我了,你說的這些,操作系統(tǒng)都封裝好了,程序們直接調(diào)用就好了,哪有那么麻煩?
。。。。。。

你說的不錯(cuò),不過有一個(gè)致命的問題,就是操作系統(tǒng)也幫不上忙。


什么問題?
跨平臺(tái)移植


你是說在移植到不同的操作系統(tǒng)上嗎?
不僅僅是操作系統(tǒng),還可能移植到別的架構(gòu)CPU上。這樣原來的程序就沒法執(zhí)行了。




提問題當(dāng)然容易,那你有什么好的解決辦法?
我的辦法就是不要讓程序代碼編譯成你的指令集的指令,而是生成一個(gè)我定義的中間碼。運(yùn)行的時(shí)候再由我來負(fù)責(zé)把它們翻譯成當(dāng)前平臺(tái)下對(duì)應(yīng)的CPU指令,交給你們CPU來執(zhí)行。


好家伙,還說不是把我架空,這樣一來,你這個(gè)中間商好賺差價(jià)啊。
不過這對(duì)您也沒什么損失嘛,反正最后還是躲不開您這一層。







我聽你這意思,那如果其他語言能編譯成你的中間碼,你也能執(zhí)行了?
那可不,除了Java,咱還能執(zhí)行Groovy、Scala,對(duì)了,Python咱也能執(zhí)行。這不跟您一樣嘛,不管是什么高級(jí)語言,最終編譯成你的指令集,你就能執(zhí)行了,這不一個(gè)道理嘛


有點(diǎn)6啊,你這個(gè)中間碼是什么樣的?有這么厲害,跟我的指令集有什么不同呢?
跟您的指令集很像,不同的是我的“指令”不像您的指令有長(zhǎng)有短,我的統(tǒng)一都是一個(gè)字節(jié),所以也叫字節(jié)碼!


都是一個(gè)字節(jié)?別蒙我了,光內(nèi)存地址都不止一個(gè)字節(jié)。
真的,我基本上都是零地址指令,要用的數(shù)據(jù)都在棧頂,直接操作就是了


都在棧頂?不用寄存器怎么進(jìn)行數(shù)據(jù)操作呢?
誰說一定要有寄存器?我就不用寄存器,您是基于寄存器架構(gòu)的,而我是基于棧式架構(gòu)的。運(yùn)算的時(shí)候直接操作棧頂?shù)臄?shù)據(jù)就行了



基于棧?你是說你的指令用到的數(shù)據(jù)都放在棧里是嗎?這棧是在內(nèi)存中,這樣的話數(shù)據(jù)不停進(jìn)進(jìn)出出就要頻繁訪問內(nèi)存,肯定很慢吧?
那肯定是比您慢了,不過我也有優(yōu)化辦法。


什么辦法,說來聽聽
Top-Of-Stack-CAching,簡(jiǎn)稱TOSCA,就是棧頂緩存。在棧頂?shù)臄?shù)據(jù)雖然名義上是在棧頂,但實(shí)際我在實(shí)現(xiàn)的時(shí)候,偷偷的放在了你的寄存器里,不僅可以減少訪問內(nèi)存的次數(shù),你到時(shí)候執(zhí)行的時(shí)候訪問起來也快得多。


好家伙,你這小子當(dāng)面一套,背后一套啊。



你開始說到了“翻譯”,你是怎么翻譯執(zhí)行這些字節(jié)碼的呢?
我們?yōu)槊總€(gè)字節(jié)碼都準(zhǔn)備了對(duì)應(yīng)的匯編指令,來完成這個(gè)字節(jié)碼定義的行為。然后把所有字節(jié)碼的匯編指令入口整合到一張表里來,我來統(tǒng)一派遣分發(fā)就可以了。這些匯編指令到時(shí)候就直接交給你CPU來執(zhí)行就好啦。



我知道了,你們的跨平臺(tái)關(guān)鍵就是在不同平臺(tái)生成對(duì)應(yīng)的的匯編指令,是吧!



不過這聽起來有點(diǎn)像是解釋執(zhí)行啊,跟那些腳本語言解釋執(zhí)行差不多嘛
你說的那些腳本語言底層是用高級(jí)語言在“模擬”執(zhí)行,而我是直接把字節(jié)碼翻譯成了匯編指令,比他們快多了。


再快,那也是解釋執(zhí)行
好吧,看來得亮出絕活了!


啥?
JIT,just-in-time compilation,即時(shí)編譯技術(shù)。


這是啥,看上去很厲害的樣子
我在派遣分發(fā)的過程中,發(fā)現(xiàn)有頻繁執(zhí)行的函數(shù)或者代碼塊,我就會(huì)啟動(dòng)即時(shí)編譯機(jī)制,將這部分代碼直接編譯成你CPU的指令,后面就不用再走字節(jié)碼派遣表執(zhí)行了


頻繁執(zhí)行的函數(shù)好理解,頻繁執(zhí)行的代碼塊是什么意思?
比如函數(shù)中某個(gè)循環(huán)體,循環(huán)執(zhí)行很多次,雖然可能這個(gè)函數(shù)調(diào)用次數(shù)不多,但循環(huán)執(zhí)行要是很多,也會(huì)觸發(fā)我的即時(shí)編譯機(jī)制


你是怎么判定是否是頻繁呢,不會(huì)是憑直覺吧
當(dāng)然不是,頻不頻繁,我心里是有“數(shù)”的。這個(gè)數(shù)就是計(jì)數(shù)器,我會(huì)統(tǒng)計(jì)函數(shù)的調(diào)用次數(shù)和循環(huán)體的執(zhí)行次數(shù)。


好小子,有兩把刷子啊,沒少花心思
雕蟲小技,不敢班門弄斧



呀!別聊了,程序員開機(jī)了,要去干活了
今天不周末嗎,他咋還來



