1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Java 執(zhí)行過程中的內(nèi)存模型

        共 1719字,需瀏覽 4分鐘

         ·

        2021-02-05 20:55

        點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

        優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

        ? 作者?|? 小z同學(xué)

        來(lái)源 |? urlify.cn/BF7zui

        76套java從入門到精通實(shí)戰(zhàn)課程分享

        一、前言

        本文的主要工作:嘗試以時(shí)間順序追蹤一遍 Java 執(zhí)行的整個(gè)過程,以及展示 JVM 中內(nèi)存模型的相應(yīng)變化。

        本文的主要目的:希望能夠通過 Java 執(zhí)行過程的冰山一角,增進(jìn)對(duì)編程語(yǔ)言工作原理的理解。

        以下面這段代碼為例,追蹤它的執(zhí)行過程:

        public?class?Car?{
        ????private?int?speed;

        ????public?void?setSpeed(int?speed)?{
        ????????this.speed?=?speed;
        ????}

        ????public?void?getSpeed()?{
        ????????System.out.println(speed);
        ????}

        ????public?static?void?main(String[]?args)?{
        ????????Car?car?=?new?Car();
        ????????car.setSpeed(3);
        ????????car.getSpeed();
        ????}
        }

        二、執(zhí)行過程

        接下來(lái)是具體的執(zhí)行過程,總共包含五個(gè)步驟:編譯、加載、執(zhí)行 main 方法、執(zhí)行成員方法、方法返回。

        Step1:編譯

        首先,在我們完成上述這段源碼之后,要想讓程序跑起來(lái),我們需要將其編譯成為字節(jié)碼文件。字節(jié)碼是一種跨平臺(tái)的JVM機(jī)器語(yǔ)言,它能夠被JVM所解析,而無(wú)關(guān)底層的操作系統(tǒng)。

        Step2:加載

        當(dāng)代碼需要被調(diào)用時(shí),JVM 會(huì)加載目標(biāo)字節(jié)碼至方法區(qū),并轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu),這里的加載過程是通過類加載器完成的。然后內(nèi)存中(不一定是堆)會(huì)生成一個(gè)代表這個(gè)類的 java.lang.Class 對(duì)象,作為方法區(qū)這個(gè)類的各種數(shù)據(jù)結(jié)構(gòu)的訪問入口。

        Step3:執(zhí)行 main 方法

        main 方法可以通過 java.lang.Class 對(duì)象進(jìn)行調(diào)用,參考如下代碼:

        Method?method?=?targetClass.getDeclareMethod("main",?String[].class);
        method.invoke(null,?(Object)?new?String[0]);

        之后 PC 寄存器將會(huì)指向方法區(qū)中的 main 函數(shù)地址,線程棧中會(huì)生成對(duì)應(yīng)的棧楨,其主要用于存放當(dāng)前方法的局部變量表、操作棧、以及方法返回地址。接下來(lái),PC 寄存器向后地址偏移,執(zhí)行引擎開始執(zhí)行 main 方法體。當(dāng)語(yǔ)句 Car car = new Car() 執(zhí)行完畢,棧楨與堆中的相應(yīng)變化如下:

        Step4:執(zhí)行成員方法

        對(duì)象 car 的 setSpeed 方法調(diào)用過程和 main 類似,通過索引 car 的成員方法地址,PC寄存器將指向方法區(qū)中的 setSpeed 函數(shù)地址,同時(shí)線程棧中將產(chǎn)生新的棧楨,其中的方法返回地址用于保存原有 PC 地址偏移。當(dāng)賦值語(yǔ)句 this.speed = speed 執(zhí)行完畢,棧楨與堆中發(fā)生的相應(yīng)變化如下:

        Step5:方法返回

        隨著 setSpeed 方法的執(zhí)行結(jié)束,Stack 中的相應(yīng)棧楨出棧,棧頂指針重新指向 main 棧楨。同時(shí) PC 寄存器將根據(jù)方法返回地址進(jìn)行還原,從而繼續(xù)執(zhí)行 main 的方法體。當(dāng) main 方法也執(zhí)行完畢出棧后,主線程與虛擬機(jī)實(shí)例銷亡,程序結(jié)束。

        三、雜談

        虛擬機(jī)或某一門程序語(yǔ)言,作為一種底層實(shí)現(xiàn),可以滿足上層用戶的絕大部分需求,但是需求是與時(shí)俱進(jìn)的,總有一天用戶需要編寫自己的底層實(shí)現(xiàn),比如組件、框架、一門新語(yǔ)言。這時(shí)需要打開原有的規(guī)范,先破壞它,再重建它,從而定義自己的規(guī)范。這也許是我們需要探究底層的緣由之一吧。




        粉絲福利:Java從入門到入土學(xué)習(xí)路線圖

        ??????

        ??長(zhǎng)按上方微信二維碼?2 秒


        感謝點(diǎn)贊支持下哈?

        瀏覽 65
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            色网中文字幕 | 久久99国产综合精品免费 | 电影院和嗯啊陌生人h | 人与野鲁毛片在线 | 亚洲精品一区二区冲田杏梨 | 放荡短裙少妇大叫受不了视频 | 一级A片处破外女 | 日本人免费xxxxhd68 | 扒开你的腿做爽爽初视频 | 水蜜桃成人视频 |