jvm虛擬機的故事之(我是一個Java class)

做者:IBM劉欣java

前言:本文主要想講一下Java虛擬機的故事, 可能有點偏門,不妥之處歡迎留言交流。服務器


wKioL1cYNICQgOvNAABOoTjjnX8301.jpg



第一回 陌生警察
dom


我出生在C盤下面一個很深層次的目錄下, 也不知道是誰把我放到這裏的。ide


我一直在睡覺,外邊的日出日落,風雨雷電和我一點關係都沒有。函數


直到有一天,有個傢伙咣咣咣砸我房門把我叫醒。優化


這個傢伙穿着像警察的制服, 左手拿着一個對講機, 右手遞過來他的工做證: "你好, 我是Classloader, 請問你是Account類嗎"spa


"是啊, 怎麼了?"線程


這個Classloader 沒回答我, 反而拿起對講機:3d


"頭兒,你看看你能不能裝載這個Account類?」調試


對講機那頭好像也在問他的上司,過了半天,終於有了迴音:


"我裝載不了, 個人上級也說了,他們也裝載不了, 你來幹吧"


"那就報數吧~」 我此次注意到旁邊站着另一個笑眯眯的小個子。


"報什麼數?" 我一臉詫異。


"唉,果真沒有被裝載過, 你是個class 文件,固然要報文件開頭的那幾個數了, 就是Java 他爸James Gosling 在jdk 1.0時肯定的那個數啊"


"奧, 我看看, 0xCAFEBABE"


"不錯, 是個java 類, 把你後邊的兩個數也報一下", 小個子繼續問


"50 , 0"


"看來版本不高啊, 是jdk 1.6編譯出來的啊", 小個子接着說 "最新的虛擬機都1.8了, 都函數式了,你造不?」


我哪裏知道? 我這才模模糊糊的回想起來, 好像是有個什麼javac 把我建立出來,扔到了這個屋子裏。


"如今奉命帶你去Java 虛擬機, 有人須要你的幫助" , 這個Classloader 態度冷冰冰的, 我不喜歡他。


"大哥,大家咋找到個人?" 我決定和小個子套近乎。


"那還不簡單, 咱們老闆有個列表, 上面列舉着全部應該檢查的目錄,咱們順藤摸瓜,一個一個找,確定能找到"


"那萬一找不到咋辦?"


"基本不可能, 你看老闆給咱們的目錄列表中有 C:\workspace\myTaobao\bin , 咱們在下面再找三級 com/mytaobao/domain, 這不就找到你了嗎,


Account.class , 話說回來, 萬一真找不到, 未來在執行時會拋出ClassNotFound異常了, 那不歸咱們管"


我後來才知道, 個人全名其實叫作com.mytaobao.domain.Account !


"來來來, 讓我驗證一下, 你這class編譯的對不對" ,小個子拿出一個放大鏡


"恩, 常量池, 訪問標識, 字段,方法... 看起來沒有問題「 , 小個子對Classloader說。


被人拿着放大鏡看,這種感受極爲不爽。


"走, 去虛擬機" , Classloader仍是冷冰冰的。


這哥倆不容我帶任何東西, 便把我推上車,飛奔向我沒據說過的「虛擬機」。


"大哥, 你叫什麼名字" , 我看小個子還算和睦。


"我就是大名鼎鼎的文件驗證器了, 能管不少事"


"那剛纔他爲啥還得請示上級呢" , 我用眼神指了一下開車的ClassLoader


文件驗證器的聲音一會兒就壓低了:


"你不知道,說來話長, 咱們以前出現過事故,有個***寫了個類java.lang.String, 和咱們老闆手下有一個幹活最賣力的員工名字如出一轍,只是這個***類裏邊居然有格式化硬盤的代碼,咱們的小兵Classloader 不明就裏,就把這個***類給先裝載了,也執行了, 最後的結果,唉,很慘的... "


"那後來怎麼辦?"


"後來咱們老闆就定下了規矩:他的骨幹員工像String, ArrayList等只能由他本身的心腹去裝載, 我據說老闆的心腹都是分層級的,像傳銷同樣, 每一個都有上線, 最頂層的叫Bootstrap Classloader , 下一次級叫Extension Classloader, 如今開車的這位其實叫App Classloader,位於最底層, 咱這位Classloader 在裝載一個類以前,必定要問一問這幾位權利極高的大爺,請他們先裝載,這幾位爺裝載不了,才由咱們這些小兵來出馬。「


"這能避免******?"


"能啊! 你想一想, 那個***寫了個***的java.lang.String, 咱們在裝載以前,確定要請示Extension, Bootstrap這些大爺先來裝載, 因爲String是老闆的核心員工,確定會他們先裝載啊, 這些大爺把String 直接就給咱們了, 咱們就不會裝載***類了"


「你能不能少說兩句」 Classloader 彷佛生氣了。


我和文件驗證器只好禁聲。


其實文件驗證器也不是隻會給我吹牛, 他也很敬業, 這傢伙在車上把我所有的字節碼都要了過去, 對這些天書通常的東西一遍一遍的檢查分析,確保每一個指令都是正確的, 檢查是否是有超類, 是否是覆蓋了final方法,跳轉指令是否是正確....


第三回 初識虛擬機


很快咱們就來到了目的地, 我一看虛擬機不就是幾個大樓嘛, 不過這幾座大樓可真是高啊。


他倆把我帶進其中一座叫「方法區」的大樓,進了電梯, 輸入2048 。


很快來到第2048層, 無數的格子間平鋪開來,他們七拐八拐,輕鬆的把我帶到了個人位置, 上面寫着個人名字「com.mytaobao.domain.Account」.


我問文件驗證器: 「這樓這麼高, 這麼多格子間, 人會坐滿嗎?」


"只有極少狀況會坐滿, 一旦滿了,那時候會拋出異常, 咱們就完蛋了。 你本身好自爲之吧, 再見 "


他們把我安頓好就馬上離開了。


我往周邊一看, 咦,這不是著名的java.lang.String嗎。


我本想和他打個招呼, 能夠他的電話彷佛一直沒斷過, 嘴裏一直說着什麼store, load之類我聽不懂可是彷佛有點熟悉的話。


正無聊着呢,我桌子上的電話也響了, 電腦屏幕也亮了,我看到一我的對我笑着說:


"你好, 我剛剛new 出來的Account對象, 個人編號是Account@659e0bfd"


暈倒 ! 這傢伙和我什麼關係?


看我一臉的詫異, 他說,「 很快就會有個線程到CPU車間了,他會聯繫你, 我就是想確認下你在不在, 奧對了, 我在一個叫作堆的地方, 有空找我玩啊, byebye 」, 說完就消失了。


果真沒多久, 視頻電話又響了。


此次我看到一我的站在一個明亮的車間裏, 抱着一個包裹, 他按了一個按鈕, 面前馬上升起一個工做臺 , 臺子上立了一個有不少抽屜的櫃子,每一個抽屜上都有一個編號, 旁邊還有一個深桶。


我正想問問問怎麼回事呢, 就聽到了他的聲音:


"我是線程0x3704, 我要調用你第二個方法了「


(碼農翻身注: 不認識線程0x3704的同窗能夠回覆「我是一個線程」查看)


我一看, 個人第二個方法是add :


public void add(int x , int y ){


x = x + y;


.....其餘代碼略....


}


(碼農翻身注: Account類固然看不到這些源碼, 這是爲了方便你看的 :-) )


"請把第一條指令給我說一下" 0x3704 繼續問我要東西


我還不太熟練,找了半天才說:


"iload_0"


因而他就操做櫃子上的機械手把0號抽屜的一個數30扔到到了工做臺上的一個桶裏,這個桶很窄,無法並排放兩個數, 可是很深。

wKiom1cYM7_BRCngAAB6IKaVMNQ156.jpg



而後0x3704說 「下一條指令」


"iload_1"


因而1號抽屜的一個數40也被扔到了桶裏,正好壓在30上面, 從桶上面就看不到30了。

wKioL1cYNIHRVW47AABwmKrPntM806.jpg


「下一條指令」


」iadd「


因而他就把兩個數從桶裏取了出來, 作了個飛快的動做, 這兩個數變成了一個數 70 !, 而後他又把70 放到了桶裏。

wKiom1cYM8CBQtdxAADXw9Wy-vA334.jpg


「下一條指令」


"istore_0"


因而他把70從桶裏撈出來, 放到了櫃子上編號爲0的地方, 以前的30就被扔掉了。


我看的目瞪口呆,這廝是在幹嗎???


我問他: 「0x3704, 不就是把兩個數加起來嗎? 爲啥搞的這麼麻煩」


他不理我, 只是繼續說, 「下一條指令」


我只有配合它玩這個遊戲。


java.lang.String 可貴的清閒, 端着一杯咖啡一邊看我手忙腳亂的取指令, 一邊說:


"新人都這樣, 彆着急,等你熟練了,閉着眼睛就搞定了, 就像我同樣,你可能不知道 , 咱們這個虛擬機叫作基於堆棧的虛擬機, 看到那個桶沒有,其實就是個先進後出的棧啊, 咱們虛擬機的全部指令其實都是在對棧進行操做"


但是我仍是好奇: 「這棧有什麼好啊」


旁邊的格子間的java.util.Stack 馬上說:


"這事兒你得問我啊, 怎麼說呢, 主要是爲了簡單, 你看咱們只用一個簡單的桶,奧對了,棧, 就能完成全部的工做, 你作要的就是往棧裏扔東西(入棧), 而後從最上面拿東西(出棧) 就好了。 不像intel 的CPU, 搞了巨多的桶,每一個桶只能容納一個數, 他們還美名其曰寄存器, 作加法的時候, 先把一個數放到第一個桶, 再把另一個數放到第二個桶,加起來之後的結果還得找個桶,有些桶還不通用,這麼多桶找起來麻煩死了。 "


"但是咱們的棧操做起來就麻煩了啊, 你看一個簡單的加法都得操做半天" ,我不依不饒。


"咱們的指令能夠優化啊, 不過這我也不太懂"


這個遊戲我整整完了一天,沒有線程找個人時候, 我就閒着, String說得對, 熟練之後簡直太簡單了。


String 就不同了, 幾乎每時每刻都線程給他打電話要指令, 這麼沒辦法, String確實是虛擬機的骨幹和精英, 使用頻繁,業務純熟,忙而不亂。


有時候我會看到線程有不止一個工做臺, 而是一摞子工做臺, 也是一個壓一個, 線程們都很老實,永遠在最上面那個工做, 歷來不會先幹下面的活。

wKiom1cYM76R3VMIAAC9Xcu5eG8963.jpg


我問java.util.Stack :"這些工做臺也是棧吧"


"猜的不錯,學名叫Java 棧,每一個線程都有一個, 其中的每一個工做臺你看過了 ,學名叫棧幀, 知道不? 每一個臺子都表明一個方法調用, 這一摞工做臺就方法調用方法致使的啊 "


確實是, 由於我發現一旦調用新方法, 馬上就會造成一個新的工做臺, 壓在老的上面。 方法調用完成後, 棧頂的工做臺就被銷燬了, 線程會在底下的工做臺繼續機械的幹活。


第四回 快樂假期


次日, 0x3704又問我要指令, 我有點生氣: 你就不會記住嗎


0x3704說: 我可不能記住, 萬一你被從新裝載了, 指令變了怎麼辦?


我告訴他指令是"iload_0" , 他剛把數據扔到桶裏, 古怪的事情發生了, 身手敏捷的0x3704忽然好像凝固了同樣,不動了。


只聽到String歡呼: 「遇到斷點了,碼農開始調試了, 咱們放假了!」


"調試?什麼調試?"


"就是碼農會單步、手工的執行這些指令,他們慢死了, 可能一秒才能執行一步, 因爲咱們的時間比他們快的多, 他們的一秒,簡直就是咱們的10幾天, 走, 出去玩去"


"出去玩? 能上哪兒玩」 我以爲這裏無聊透頂。


"找咱們new 出來的對象玩去"


我想到了以前聯繫過個人 對象Account@659e0bfd , 想着去看看也不錯。


這個叫"堆"的大樓更加擁擠, 全是人, String 的對象固然最多,Stirng類左右逢源,不停的打招呼, 從我建立出來的Account對象幾乎找不到。


一隊全副武裝的士兵不停的在巡邏, 時不時的把對象拉出來,塞到車裏去。


「這是在幹嗎啊」 我問String類


"這些人叫清理者, 專門清理沒有用的對象, 你看,車裏那不是Account@659e0bfd 嗎"


"啊? 昨天我還和他聯繫, 他怎麼會沒用了呢"


"他頗有可能只是個方法的局部變量, 方法結束後, 就沒人引用了, 白白的佔用空間, 你看這樓太擁擠了, 若是不清理, 很快就會住滿,系統崩潰, Out Of Memory了"


"那這個樓就不能蓋的更高點嗎?」 我內心有點可憐這些被回收的對象們


"樓有多高,是由碼農們決定的, 他們在啓動虛擬機的時候會指定參數"


"那士兵咋知道誰有用沒用?"


"引用計數唄, 若是對象被使用, 計數就會增長, 不用的時候就會減小, 若是是0 , 那就可能被清理了。"


"那咱們會被清理掉嗎?" 我擔憂的問


String類神祕的笑了下: "我應該不會, 可是你是有可能的"


我固然明白了, String類是核心員工, 而我只是從外邊加載過來的一個類而已, 不過我也確實有點想個人家了。


果真,又過了10天, 0x3704才動彈了一下,問我要第二條指令


我想都沒想就告訴了他:「iload_1」 。


接下來又是10天的長假。


第五回 真相大白


漫長的調試假期終於結束了,我剛回到本身的工做間, 發生了更奇怪的事情, 整個世界毫無徵兆的消失了。


我暈暈乎乎,發現仍是躺在自家牀上, 我是作了一場夢嗎?


但是過去的記憶如此的真切, 究竟是怎麼回事?


管它呢, 我已經知道了本身所在的房子的門牌號是 C:\workspace\myTaobao\bin\com\mytaobao\domain


探索一下吧,唉 , 大部分人都很是無趣,不理我。


正當我準備要回去接着睡覺的時候, 我先發現了C:\workspace\myTaobao\src\ 下也有個如出一轍的目錄com\mytaobao\domain,關鍵是裏邊居然有個Account.java !


出生的模糊記憶告訴我, javac 就是從這裏把我生成的。


我正要給他打招呼,一個"hi"還沒說出口。


javac 又一次運行, 我被新的Account.class 殘忍的覆蓋掉了!


臨死前, 我終於明白了,這個一個碼農的電腦,碼農在開發程序, 調試程序, 不斷的重啓服務器。


而我這個類隱藏着一個Bug, 通過調試後被發現, 而後Fix了!

相關文章
相關標籤/搜索