Inside the Java Virtual Machine 讀書筆記一

來源:互聯網
上載者:User

標籤:jvm   heap   stack   執行個體   

what?

說jvm,可能指的是:

  • the abstract specification,
  • a concrete implementation, or
  • a runtime instance.

一個運行時的虛擬機器執行個體( a runtime instance)就是負責運行一個java程式,這個執行個體隨著java程式的開始(main方法運行)而產生,結束而消失。

java虛擬機器中有兩種線程,守護線程與非守護線程,像gc這種後台線程就是守護線程,而main方法產生的是非守護線程。當所有的非守護線程結束,則jvm結束。

JVM(此處指:the abstract specification)定義了抽象的組成部分,以及它們之間的互動方式,來定義JVM的實現(a concrete implementation):

每個JVM都有一個 class loader subsystem,當類或介面(必須完全限定名)裝載到JVM中,會被裝載到class loader subsystem中.同樣,每個JVM會有一個execution engine,負責執行載入的class中方法指令。

.Class檔案與byteCode(位元組碼)

Class檔案包含有代碼以及支援代碼用的中繼資料(metadata)。代碼部分就是位元組碼,而中繼資料部分則包括諸如泛型等許多資訊。所以說Class檔案包含位元組碼,但不只有位元組碼。

Class Loader subclass

takes care of finding and loading types

jvm有兩種類裝載器:a primordial class loader and class loader objects(原始類裝載器:jvm的一部分,使用者自訂的類裝載器對象:java程式的一部分 )。對於類裝載器對象(java程式)都必須繼承自
java.lang.ClassLoader.ClassLoader中定義的介面方法,提供了對JVM訪問的機制。對於JVM中每個被裝載的類型,都會產生一個java.lang.class對象代表它,和其他Object對象一樣,對象的產生都在Heap中,而類型資訊都放在Method Area.

類裝載器除了要定位、匯入二進位Class檔案外,還必須驗證匯入類的正確性,為類變數分配並初始化記憶體

大致順序:

  1. Loading: finding and importing the binary data for a type
  2. Linking: performing verification, preparation, and (optionally) resolution
    a. Verification: ensuring the correctness of the imported type
    b. Preparation: allocating memory for class variables and initializing the memory to default
    values
    c. Resolution: transforming symbolic references from the type into direct references.
  3. Initialization: invoking Java code that initializes class variables to their proper starting values.
runtime data areas

當JVM運行時,它需要記憶體去儲存,比如位元組碼等其他從class檔案中擷取的資訊,對象執行個體化,方法參數,傳回值,局部變數,計算結果的媒介等等。於是每個JVM定義了多個 runtime data areas 去組織這些執行程式需要的記憶體。(各種JVM會根據這些抽象的定義,產生各種不同的具體實現)。

Method Area && Heap

每個JVM執行個體有一個Method Area 和一個Heap,這個MethodArea 、Heap被這個JVM中的所有線程所共用。當一個JVM使用classLoader正確定位並裝載了class 檔案,它會從這些二進位資訊中解析出類型資訊,並把這些類型資訊放入MethodArea中,並把其中的對象執行個體放入Heap中。

我說了method area主要放類型資訊,所謂類型資訊指:

Type Information

For each type it loads, a Java Virtual Machine must store the following kinds of information in the
method area:

  • The fully qualified name of the type

  • The fully qualified name of the typeís direct superclass (unless the type is an interface or class java.lang.Object, neither of which have a superclass)

  • Whether or not the type is a class or an interface

  • The typeís modifiers ( some subset of` public, abstract, final)

  • An ordered list of the fully qualified names of any direct superinterfaces

其實通過java.lang.Class的方法,我們可以動態擷取儲存在MethodArea裡的一些類型資訊:

public String getName();public Class getSuperClass();public boolean isInterface();public Class[] getInterfaces();public ClassLoader getClassLoader()

另外,MethodArea還包括這些:

  • The constant pool for the type
    每個Type(類或介面)都有一個constant pool。它是一個有序集合,其中存放基本類型的引用,還有類型(類或介面)的引用、類變數引用、方法引用。

  • Field information
    儲存 類變數的資訊:類變數的類型、名稱、修飾符(如private、public 、final、static等等)

  • Method information
    方法名、方法傳回值、方法修飾符號、方法參數列表、還有方法的位元組碼、方法拋出的異常列表(非abstract 、native 方法)。

  • All class ( Static Fields) variables declared in the type, except constants

  • A reference to class ClassLoader
    JVM需要追蹤類型(type,指類或介面)是否被載入原始classLoader或classLoader的對象,因此method Area需要儲存一個classloader的引用。

  • A reference to class Class
    JVM對每個載入的類型(interface\class)都會建立一個java.lang.class的執行個體。並且,JVM還要用某種方式,將這個java.lang.class執行個體與它的Type Information(存在與MethodArea) 關聯起來。
    通過這個靜態方法,你可以擷取任何載入到classLoader裡的類型對應的java.lang.class執行個體。

public static Class forName(String className)

另外一種方法擷取class,是每個類型執行個體的getClass()方法。

        System.out.println(Class.forName("java.lang.String"));        System.out.println(new String().getClass());

When the Java Virtual Machine loads a type, it uses a class loader to
locate the appropriate class file. The class loader reads in the class
file–a linear stream of binary data– and passes it to the virtual
machine. The virtual machine extracts information about the type from
the binary data and stores the information in the method area. Memory
for class (static) variables declared in the class is also taken from
the method area


用一個執行個體來描述一下JVM的動作:

class Lava {    private int speed = 5; // 5 kilometers per hour    void flow() {    }}public class Volcano {    public static void main(String[] args) {        Lava lava = new Lava();        lava.flow();    }}

運行程式,JVM找到並讀取Volcano.class檔案,然後在引入的Volcano.class檔案中讀取Volcano類的資訊,將這些資訊放入Method Area中。然後JVM通過解釋Method Area中的codeByte調用main方法。
注意,當JVM執行main()時,它並沒有載入Lava.class,它會按需載入。
執行main()時, JVM調用足夠的記憶體空間給CostantPool的第一條Volcano類,然後在Volcano的ConstantPool中找類Lava的引用符號(就是字元“Lava”),它會檢查Lava是否被載入。當JVM發現沒有,就會尋找並讀取Lava.class檔案,然後從二進位的Lava.class中讀取資訊,並放入MethodArea.緊接著, JVM會把剛才ConstantPool的首條的指標(指向Volcano的指標)替換為指向方法區Lava類資料的指標,以後用這個指標快速存取Lava。
接下來,JVM通過ConstantPool的首條指標(指向MethodArea的Lava資訊),來快速擷取Lava資訊,並按需分配足夠記憶體。

(JVM總是通過MethodArea類型資訊去判斷需要調用多少記憶體)當JVM確定了記憶體大小,就去堆上分配,並把這個對象的speed變數初始化為0.然後,把產生的Lava對象的引用壓入棧中。

Lava lava = new Lava();這個程式碼完成了。

然後,調用flow()。

資料類型

JVM通過在多種類型的資料上進行操作來完成計算。
基本類型儲存值、參考型別指向對象。(基本類型與參考型別的區別,很簡單)

這裡要提boolean,雖然它也被定義為基本類型,但是java編譯器把源碼編譯為位元組碼,裝載在JVM中,boolean被用int或byte來表示,0表示false;非0整數被表示true.

Heap

Heap用來存放執行個體化對象或數組,會調用分配來自heap的記憶體空間。也就是說,對象本身(memory)在heap上建立。
兩個Java application 不可能共用Heap,當一個java application 的不同線程可以共用,因此,我們在多線程中,同步的使用一個對象。

另外,代碼中可以去決定什麼時候建立對象,但是不能決定什麼時候銷毀對象(釋放記憶體)。這個完全有JVM自己決定(GC管理heap,除了釋放空間,它還會移動對象來減少記憶體片段)。

我們已經知道,棧中存放執行堆中對象的引用,除此,堆中對象內部還會保留一個執行方法區的引用(為了快速存取類型資訊)。

對於heap的兩種實現:

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Inside the Java Virtual Machine 讀書筆記一

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.