JVM第三篇 — JVM是怎麼工做的?

    本文摘自: http://blog.163.com/guixl_001/blog/static/41764104201082961141664/,並稍加整理。ui

package demo;

public class Volcano {
    public static void main(String[] args) {
        Lava lava = new Lava();
        lava.flow();
    }
}

class Lava {
    private int speed = 5;
    void flow() {
        speed++;
        System.out.println(speed);
    }
}

    下面咱們描述一下main()方法的第一條指令的字節碼是如何被執行 的。不一樣的JVM有不一樣的實現,這只是其中的一種實現。指針

    爲了運行這個程序,咱們會以某種方式把「demo.Volcano"傳給JVM,JVM找到並讀取這個類文件;它從類文件提取類型信息並寫入方法區,經過解析方法區中的字節碼激活main()方法。 在執行時,JVM保持了一個指向當前類Volcano的常量池的指針。code

    注意,JVM在尚未加載Lava類的時候就已經開始執行了。正像大多數的 JVM同樣,不是等全部類都加載了之後纔開始執行,而是隻會在須要的時候作加載。對象

    main()的第一條指令告知JVM對位於常量池中第一項的類作初始化:JVM經過指向Volcano常量池的指針找到第一項,發現是一個對Lava類的符號引用,而後它就檢查方法區看Lava類是否已被加載。blog

    這個符號引用就是類Lava類的完整有效名「demo.Lava」, 當JVM發現尚未加載過名稱爲「demo.Lava」的類,它就開始查找並加載類文件"demo.Lava.class",從類文件中抽取類型信息並寫入方法區。get

    而後,JVM以一個直接指向方法區Lava類的指針替換了常量池第一項的符號引用,以後就能夠用這個指針快速的找到Lava類了。而這個替換過程也稱爲常量池解析(constant pool resolution)。io

    終於,JVM開始爲新的Lava對象分配空間了:JVM經過指向Lava類的指針(剛纔指向volcano常量池第一項的指針)獲得一個Lava對象究竟須要多少空間。 一旦JVM知道了一個Lava對象所要的空間,它就在堆上分配這個空間併爲實例變量初始化正確的值。class

    當把新生成的Lava對象的引用壓到棧中,第一條指令也結束了。下面的指令會用這個引用激活Lava對象的flow()方法。gui

相關文章
相關標籤/搜索