小師妹學(xué)JVM之:java的字節(jié)碼byte code簡(jiǎn)介

簡(jiǎn)介

Byte Code也叫做字節(jié)碼,是連接java源代碼和JVM的橋梁琼娘,源代碼編譯成為字節(jié)碼,而字節(jié)碼又被加載進(jìn)JVM中運(yùn)行附鸽。字節(jié)碼怎么生成,怎么查看字節(jié)碼坷备,隱藏在Byte Code背后的秘密是什么呢?快跟小師妹一起來(lái)看看吧省撑。

Byte Code的作用

小師妹:F師兄赌蔑,為什么Java需要字節(jié)碼呢?直接編譯成為機(jī)器碼不是更快嗎竟秫?

小師妹娃惯,Java的設(shè)計(jì)初衷是一次編寫,到處運(yùn)行肥败。為了兼容各個(gè)平臺(tái)的運(yùn)行環(huán)境趾浅,java特別為各種平臺(tái)設(shè)計(jì)了JVM愕提。

我們可以把JVM看做是一種抽象,對(duì)外提供了統(tǒng)一的接口皿哨。這樣我們只需要編寫符合JVM規(guī)范的代碼揪荣,即可在JVM中運(yùn)行。

回想下之前我們提到過(guò)的java的執(zhí)行過(guò)程:

image
  1. 編寫java代碼文件比如Example.java
  2. 使用java編譯器javac將源文件編譯成為Example.class文件
  3. JVM加載生成的字節(jié)碼文件往史,將其轉(zhuǎn)換成為機(jī)器可以識(shí)別的native machine code執(zhí)行

小師妹:F師兄仗颈,我有一個(gè)大膽的想法,JVM的作用是將字節(jié)碼解釋或者編譯成為機(jī)器碼椎例。然后在相應(yīng)的運(yùn)行環(huán)境中執(zhí)行挨决。那么有沒(méi)有可能,不需要JVM订歪,不需要機(jī)器碼脖祈,而是直接在對(duì)應(yīng)的平臺(tái)上執(zhí)行字節(jié)碼呢?

愛(ài)因斯坦說(shuō)過(guò)沒(méi)有想像力的靈魂刷晋,就像沒(méi)有望遠(yuǎn)鏡的天文臺(tái)盖高。小師妹你這個(gè)想法很好,這種實(shí)現(xiàn)有個(gè)專業(yè)的說(shuō)法叫做:Java processor眼虱。

Java processor就是用硬件來(lái)實(shí)現(xiàn)的JVM喻奥。因此字節(jié)碼可以直接在Java processor中運(yùn)行。

其中比較出名的是Jazelle DBX捏悬,這是一個(gè)主要支持J2ME環(huán)境的硬件架構(gòu)撞蚕。為了提升java在手機(jī)端的執(zhí)行速度。

但是這樣做其實(shí)也是有缺點(diǎn)的过牙,后面我們會(huì)講到甥厦,java字節(jié)碼中的指令非常非常多。所以如果用硬件來(lái)實(shí)現(xiàn)的話寇钉,就會(huì)非常非常復(fù)雜刀疙。

一般來(lái)說(shuō)Java processor不會(huì)實(shí)現(xiàn)全部的字節(jié)碼中的功能,只會(huì)提供部分的實(shí)現(xiàn)扫倡。

查看Byte Code字節(jié)碼

小師妹:F師兄谦秧,那使用javac編譯過(guò)后的class文件跟字節(jié)碼有什么關(guān)系呢?

class文件中大部分都是byte code镊辕,其他的部分是一些meta data元數(shù)據(jù)信息油够。這些組合在一起就是class文件了。

小師妹:F師兄征懈,你說(shuō)class文件是byte code石咬,為什么我在IDE中打開的時(shí)候,直接顯示的是反編譯出來(lái)的源文件呢鬼悠?

小師妹,這是IDE的一個(gè)便利功能焕窝。因?yàn)榇蠖鄶?shù)情況下,沒(méi)有人想去看class文件的Byte code的它掂,大家都是想去看看這個(gè)class文件的源文件是什么樣的。

我們舉個(gè)最簡(jiǎn)單的例子:

image

這個(gè)類中虐秋,我們定義了一個(gè)很簡(jiǎn)單的testByteCode方法,里面定義了兩個(gè)變量用押,然后返回他們兩個(gè)的和靶剑。

現(xiàn)在有兩種方法來(lái)查看這個(gè)類的Byte Code:

第一種方法是用javap命令:

javap -c ByteCodeUsage.class
image

生成的結(jié)果如上所示。

第二種方法就是在IDEA中缎讼,選中class文件阐污,然后在view中選中show Bytecode:

image

我們看下輸出結(jié)果:

image

兩個(gè)的結(jié)果在顯示上面可能有細(xì)微的差異笛辟,但是并不影響我們后面對(duì)其的解析。

java Byte Code是怎么工作的

小師妹:F師兄手幢,能講解一下這些byte code到底是怎么工作的嗎忱详?

首先我們要介紹一下JVM的實(shí)現(xiàn)是基于棧的結(jié)構(gòu)的。為什么要基于棧的結(jié)構(gòu)呢匈睁?那是因?yàn)闂J亲钸m合用來(lái)實(shí)現(xiàn)function互相調(diào)用的。

我們?cè)倩仡櫼幌律厦娴膖estByteCode的字節(jié)碼胀蛮。里面有很多iconst,istore的東西粪狼,這些東西被稱作Opcode,也就是一些基于棧的操作指令再榄。

上面講了java bytecode的操作指令其實(shí)有很多個(gè)狡刘。下面我們列出這些指令的部分介紹:

image

實(shí)在是太多了困鸥,這里就不把所有的列出來(lái)了。

我們看到的指令名字其實(shí)是一個(gè)助記詞疾就,真實(shí)的Opcode是一個(gè)占用兩個(gè)字節(jié)的數(shù)字。

下面我們來(lái)詳細(xì)解釋一下testByteCode方法:

public int testByteCode();
    Code:
       0: iconst_1
       1: istore_1
       2: iconst_2
       3: istore_2
       4: iload_1
       5: iload_2
       6: iadd
       7: ireturn

第一步瘪板,iconst_1將int 1加載到stack中漆诽。

第二步,istore_1將入棧的int 1出棧厢拭,并存儲(chǔ)到變量1中。

第三步畦贸,iconst_2將int 2入棧。

第四步薄坏,istore_2將入棧的int 2出棧寨闹,并存儲(chǔ)到變量2中。

第五步繁堡,iload_1將變量1中的值入棧。

第六步椭蹄,iload_2將變量2中的值入棧。

第七步罩润,iadd將棧中的兩個(gè)變量出棧,并相加哨啃。然后將結(jié)果入棧。

第八步拳球,ireturn將棧中的結(jié)果出棧。

這幾步實(shí)際上完美的還原了我們?cè)趖estByteCode方法中定義的功能祝峻。

當(dāng)然我們只介紹了最賤的byte code命令,通過(guò)這些簡(jiǎn)單的命令可以組合成為更加復(fù)雜的java命令酬姆。

總結(jié)

本文介紹了java byte code的作用和具體的指令奥溺,并分析了一個(gè)簡(jiǎn)單的例子來(lái)做說(shuō)明。希望大家能夠掌握浮定。

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/jvm-byte-code/

本文來(lái)源:flydean的博客

歡迎關(guān)注我的公眾號(hào):程序那些事,更多精彩等著您立美!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末方灾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子裕偿,更是在濱河造成了極大的恐慌,老刑警劉巖拢蛋,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔫巩,死亡現(xiàn)場(chǎng)離奇詭異圆仔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)坪郭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門歪沃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)嗦锐,“玉大人奕污,你說(shuō)我怎么就攤上這事√寄” “怎么了缘眶?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)巷懈。 經(jīng)常有香客問(wèn)我,道長(zhǎng)柔逼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任愉适,我火速辦了婚禮癣漆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘癌蓖。我一直安慰自己,他們只是感情好租副,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布用僧。 她就那樣靜靜地躺著,像睡著了一般责循。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上院仿,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音剥汤,去河邊找鬼。 笑死吭敢,一個(gè)胖子當(dāng)著我的面吹牛若贮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谴麦,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼匾效!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起野宜,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤魔策,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后闯袒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡其徙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年喷户,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闹获。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恼五,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出灾馒,到底是詐尸還是另有隱情睬罗,我是刑警寧澤轨功,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布古涧,位于F島的核電站花盐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏算芯。R本人自食惡果不足惜柒昏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一职祷、第九天 我趴在偏房一處隱蔽的房頂上張望届囚。 院中可真熱鬧,春花似錦意系、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至夹攒,卻和暖如春琅捏,著一層夾襖步出監(jiān)牢的瞬間递雀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工搜吧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杨凑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓僵刮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親搞糕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354