1. 程式人生 > >JVM中的方法區(Method Area)

JVM中的方法區(Method Area)

     下面我們描述一下main()方法的第一條指令的位元組碼是如何被執行的。不同的JVM實現的差別很大,這裡只是可能的其中之一的情形。 
     為了執行這個程式,你以某種方式把“Volcano”傳給了JVM。有了這個名字,JVM找到了這個類檔案(Volcano.class)並讀入,它從類檔案提取了型別資訊並放在了方法區中,通過解析存在方法區中的位元組碼,JVM激活了main()方法,在執行時,JVM保持了一個指向當前類(Volcano)常量池的指標。 
     注意JVM在還沒有載入Lava類的時候就已經開始執行了。正像大多數的JVM一樣,不會等所有類都載入了以後才開始執行,它只會在需要的時候才載入。 
     main()的第一條指令告知JVM為常量池第一項的類分配足夠的記憶體。JVM使用指向Volcano常量池的指標找到第一項,發現是一個對Lava類的符號引用,然後它就檢查方法區看Lava是否已經被載入了。 
     這個符號引用僅僅是類Lava的完整有效名“Lava”。這裡我們看到為了JVM能儘快從一個名稱找到一個類,一個良好的資料結構是多麼重要。這裡JVM的實現者可以採用各種方法,如hash表,查詢樹等等。同樣的演算法可以用於Class類的forName()的實現。 
     當JVM發現還沒有載入過一個稱為"Lava"的類,它就開始查詢並載入類檔案"Lava.class"。它從類檔案中抽取型別資訊並放在了方法區中。 
     JVM於是以一個直接指向方法區Lava類的指標替換了常量池第一項的符號引用。以後就可以用這個指標快速的找到Lava類了。而這個替換過程稱為常量池解析(constant pool resolution)。在這裡我們替換的是一個native指標。 
     JVM終於開始為新的Lava物件分配空間了。這次,JVM仍然需要方法區中的資訊。它使用指向Lava資料的指標(剛才指向Volcano常量池第一項的指標)找到一個Lava物件究竟需要多少空間。 
     JVM總能夠從儲存在方法區中的型別資訊知道某型別物件需要的空間。但一個物件在不同的JVM中可能需要不同的空間,而且它的空間分佈也是不同的。(譯者:這與在C++中,不同的編譯器也有不同的物件模型是一個道理) 
一旦JVM知道了一個Lava物件所要的空間,它就在堆上分配這個空間並把這個例項的變數speed初始化為預設值0。假如lava的父物件也有例項變數,則也會初始化。 
     當把新生成的Lava物件的引用壓入棧中,第一條指令也結束了。