JVM字節(jié)碼執(zhí)行引擎

一病毡、運(yùn)行時(shí)棧幀結(jié)構(gòu)

棧幀(Stack Frame)是用于JVM執(zhí)行方法調(diào)用和方法執(zhí)行的數(shù)據(jù)結(jié)構(gòu)祭务,是虛擬機(jī)棧的元素。棧幀存儲(chǔ)了方法的局部變量表丁溅、操作數(shù)棧唤蔗、動(dòng)態(tài)鏈接和和方法返回地址等信息。每一個(gè)方法從調(diào)用開(kāi)始到執(zhí)行結(jié)束,都對(duì)應(yīng)著一個(gè)棧幀的入棧到出棧妓柜。

一個(gè)線程中方法調(diào)用鏈可能會(huì)很長(zhǎng)箱季,在活動(dòng)線程中,只有位于棧頂?shù)臈?/strong>才是有效的棍掐,成為當(dāng)前棧幀藏雏,執(zhí)行引擎運(yùn)行的所有字節(jié)碼指令,都只針對(duì)當(dāng)前棧幀進(jìn)行操作作煌。

在調(diào)用實(shí)例方法(非static方法)時(shí)掘殴,默認(rèn)第0位的slot傳遞的是方法所屬對(duì)象實(shí)例的引用(也就是方法的接收者,JVM在調(diào)用方法時(shí)粟誓,會(huì)去方法接收者那里)奏寨,方法中可以通過(guò)this訪問(wèn)到這個(gè)隱含的參數(shù)。

棧幀.png

1.1 局部變量表

一組變量值存儲(chǔ)空間鹰服,用于存放方法參數(shù)和局部變量病瞳。
表中的slot是可以復(fù)用(不是已經(jīng)復(fù)用)的,如果當(dāng)前程序計(jì)數(shù)器的值已經(jīng)超過(guò)某個(gè)局部變量的作用于悲酷,那么變量對(duì)應(yīng)的Slot就可以給其他變量使用套菜。
請(qǐng)思考以下代碼是否可以收回局部變量空間?

   public static void main(String[] args)
   {
            {
                 byte[] placeHolder = new byte[64 * 1024 * 1024];
            }
            System.gc();
   }

分析:placeHolder是否被回收的關(guān)鍵舔涎,在于局部變量表中的Slot是否還存有對(duì)象placeHolder的引用笼踩。gc的時(shí)候,雖然已經(jīng)離開(kāi)了placeHolder的作用域亡嫌,但是在此之后嚎于,沒(méi)有對(duì)于局部變量表的任何讀寫操作,placeHolder所占用的slot還沒(méi)有被復(fù)用挟冠,所以作為GC Roots的局部變量表仍然保持著對(duì)它的關(guān)聯(lián)于购。
注意:
類變量或?qū)嵗兞浚瑳](méi)有賦值也可以使用知染,因?yàn)橛辛阒道呱5蔷植孔兞繘](méi)有賦值則不能使用。(估計(jì)原因是局部變量很多控淡,作用域有很短嫌吠,消亡很快,如果都賦零值掺炭,性能影響比較大辫诅,沒(méi)有必要

1.2 操作數(shù)棧(Operand Stack)

方法剛開(kāi)始執(zhí)行時(shí),操作數(shù)棧是空的涧狮。在執(zhí)行過(guò)程中炕矮,會(huì)有各種指令往操作數(shù)棧中讀寫內(nèi)容么夫。

1.3 動(dòng)態(tài)鏈接

每個(gè)棧幀都包含一個(gè)指向運(yùn)行時(shí)常量池中,該棧幀所屬方法的引用肤视。字節(jié)碼中的方法調(diào)用指令就以常量池中指向方法的符號(hào)引用作為參數(shù)

1.4 方法返回地址

正常退出時(shí)档痪,調(diào)用者的PC計(jì)數(shù)器的值可以作為返回地址邢滑。

二腐螟、方法調(diào)用

方法調(diào)用并不等于方法執(zhí)行,方法調(diào)用階段唯一任務(wù)就是確定被調(diào)用方法的版本(即調(diào)用哪個(gè)方法)殊鞭。

2.1 解析調(diào)用

所有方法在class文件中都是常量池中的符號(hào)引用遭垛,在類解析階段

  • 一部分符號(hào)引用會(huì)轉(zhuǎn)化為直接引用
    前提:編譯期可知,運(yùn)行期不變操灿。符合這個(gè)要求的主要包括靜態(tài)方法和私有方法锯仪。

解析調(diào)用一定是靜態(tài)的過(guò)程,在編譯期就完全確定趾盐,在類加載的解析階段就會(huì)把涉及的符號(hào)引用替換為可確定的直接引用庶喜。

2.2 分派調(diào)用
           Human human = new Man();

Human 稱為變量的靜態(tài)類型,Man稱為實(shí)際類型救鲤。

  • 靜態(tài)分派
    依賴靜態(tài)類型來(lái)定位方法的分派動(dòng)作久窟,稱為靜態(tài)分派。
    重載(Overload)屬于靜態(tài)分派本缠。
    注:
    如果參數(shù)是類似byte斥扛、char、int丹锹、Object的重載稀颁,定位方法時(shí)會(huì)在可以轉(zhuǎn)換的前提下,從小到大楣黍,依次匹配匾灶。

  • 動(dòng)態(tài)分派
    覆蓋(Override)屬于動(dòng)態(tài)分派。

      Human  man = new Man();
      Human woman = new Woman();
      man.sayHello();
      woman.sayHello();

man 和 woman 是將要執(zhí)行的sayHello()方法的所有者租漂,稱為接收者阶女。方法的接收者和參數(shù),統(tǒng)稱為方法的宗量哩治。根據(jù)分派基于多少種宗量秃踩,可將分派劃分為單分派和多分派

    public class Dispatch {
    class QQ {}
    class 360 {}
    public class Father 
    {
         public hardChoice (QQ qq)
        {
             System.out.println("Father choice QQ.");
        }

        public hardChoice (360 args)
       {
             System.out.println("Father choice 360.");
       }
  }

public class Son 
{
    public hardChoice (QQ qq)
   {
        System.out.println("Son choice QQ.");
   }

  public hardChoice (360 args)
   {
        System.out.println("Son choice 360.");
   }
}

public static void main(String[] args)
{
         Father father = new Father();
         Father son = new Son();
         father.hardChoice(new _360());
         son.hardChoice(new QQ());
}

最終決定調(diào)用方法版本的因素憔杨,就是方法的宗量(方法接收者(實(shí)際類型) + 參數(shù)類型(靜態(tài)類型))

    public void doSomeThing(Map map)
    {
          // doSomeThing
    }
   
   // 調(diào)用方法
   doSomeThing(new HashMap());
   所以其實(shí)這個(gè) new HashMap(), 會(huì)被隱含的轉(zhuǎn)為 (Map)new HashMap(), 
   也即用的是參數(shù)的靜態(tài)類型去調(diào)用方法驾孔。
  • JVM 動(dòng)態(tài)分派的實(shí)現(xiàn)
    為類在方法區(qū)建立一個(gè)虛方法表
    虛方法表存放著各個(gè)方法的實(shí)際入口地址翠勉,如果某個(gè)方法在子類沒(méi)有override妖啥,那子類虛方法表中入口地址和父類的一樣。如果覆蓋了对碌,子類的方法表中的入口地址會(huì)替換為子類版本的入口地址。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末朽们,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子骑脱,更是在濱河造成了極大的恐慌菜枷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叁丧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡拥娄,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門牡昆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)摊欠,“玉大人丢烘,你說(shuō)我怎么就攤上這事凄硼。” “怎么了摊沉?”我有些...
    開(kāi)封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)骏全。 經(jīng)常有香客問(wèn)我尼斧,道長(zhǎng)姜贡,這世上最難降的妖魔是什么棺棵? 我笑而不...
    開(kāi)封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任熄捍,我火速辦了婚禮母怜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碟贾。我一直安慰自己,他們只是感情好袱耽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布干发。 她就那樣靜靜地躺著,像睡著了一般铐然。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沥阳,一...
    開(kāi)封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天自点,我揣著相機(jī)與錄音桐罕,去河邊找鬼。 笑死功炮,一個(gè)胖子當(dāng)著我的面吹牛术唬,可吹牛的內(nèi)容都是我干的薪伏。 我是一名探鬼主播粗仓,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼塘淑!你這毒婦竟也來(lái)了蚂斤?” 一聲冷哼從身側(cè)響起存捺,我...
    開(kāi)封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤捌治,失蹤者是張志新(化名)和其女友劉穎岗钩,沒(méi)想到半個(gè)月后肖油,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年疲恢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瓷胧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片显拳。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杂数,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出揍移,到底是詐尸還是另有隱情反肋,我是刑警寧澤那伐,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布罕邀,位于F島的核電站养距,受9級(jí)特大地震影響诉探,放射性物質(zhì)發(fā)生泄漏棍厌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一阳液、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧帘皿,春花似錦畸陡、人聲如沸鹰溜。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)墓陈。三九已至,卻和暖如春贡必,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仔拟。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留科侈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓臀栈,卻偏偏與公主長(zhǎng)得像挠乳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子欲侮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 概述 執(zhí)行引擎是Java虛擬機(jī)最核心的組成部分之一威蕉。“虛擬機(jī)”是一個(gè)相對(duì)于“物理機(jī)”的概念韧涨,這兩個(gè)機(jī)器都有代碼執(zhí)行...
    胡二囧閱讀 888評(píng)論 2 2
  • 在前面兩篇文章中介紹了 .class 文件的結(jié)構(gòu)和虛擬機(jī)加載 .class 文件的過(guò)程,在本篇文章中主要介紹加載進(jìn)...
    lijiankun24閱讀 4,708評(píng)論 2 21
  • Java虛擬機(jī)的執(zhí)行引擎:輸入的是字節(jié)碼文件如孝,處理過(guò)程是字節(jié)碼解析的等效過(guò)程娩贷,輸出的是執(zhí)行結(jié)果第晰。本章主要是從概念模...
    maxwellyue閱讀 542評(píng)論 0 0
  • 關(guān)于寫文字這件事兒茁瘦, 一直覺(jué)得是件特難堅(jiān)持的事品抽, 覺(jué)得自己文筆不好甜熔,然后就時(shí)不時(shí)的給自己找理由找借口偷懶。每次看著...
    路成閱讀 247評(píng)論 0 0
  • 我的老家是在浙江盆昙,也是個(gè)臺(tái)風(fēng)高發(fā)地,夏天一來(lái)動(dòng)不動(dòng)臺(tái)風(fēng)就來(lái)來(lái)回回幾次弱左。但浙江的臺(tái)風(fēng)和廈門的臺(tái)風(fēng)還是有所區(qū)別的,廈門...
    陳木蒙閱讀 394評(píng)論 0 0