我所理解的JVM(四):對象的建立、佈局、訪問和銷燬

1、對象的建立過程java

  1. 定位到方法區常量池的類,檢查類是否已經被加載、驗證、準備、解析。
  2. 檢查類是否已經進行過初始化。
  3. 在內存中分配空間
  4. 設置對象的默認初始值(0,false,null)
  5. 執行<clint>()方法(類變量的賦值和靜態代碼塊)
  6. 執行構造
  7. 在線程棧中設置對象引用

2、 對象在內存中的佈局程序員

  對象在內存中存儲的佈局能夠分爲3塊區域:對象頭(Header)、實例數據(InstanceData)和對齊填充(Padding)。數組

  每個堆中的對象在HosPost虛擬機中都有一個對象頭(ObjectHeader),對象頭裏存儲兩部分信息:一部分是運行時對象自身的哈希碼值(HashCode)、GC分代年齡(Generational GC Age)、鎖標誌位(佔用2個bit的位置)等信息,另外一部分是指向方法去中的類型信息的指針。若是是數組對象的話,還會有額外一部分用來存儲數組長度。佈局

  實例數據是程序代碼中定義的各類類型的字段內容。線程

  對齊填充並非必然存在的,僅僅在對象的大小不是8字節的整數倍時起佔位符的做用。指針

3、對象的訪問方式:1,句柄;2,直接指針code

  句柄:java堆中劃出一塊空間單獨存放句柄池,java棧中的reference指向句柄池中的某個句柄,句柄包含兩部分信息:堆中實例對象地址和方法區中對象類型信息。對象

  直接指針:java棧中的reference指向java堆中的實例對象,每一個實例對象上有一部分信息是用來指向該對象在方法區中的類型信息。內存

  句柄的優點:當對象發生改變時,reference的值不用變,只須要改變句柄的實例指針,reference自身不須要改變。虛擬機

  直接指針的優點:節省了一次指針定位的開銷,速度更快。

  HosPot虛擬機採用第二種方式。

4、對象完成使命後,等待GC進行垃圾回收。銷燬對象即清理對象所佔用的內存空間,會調用對象的finalize()方法。

注意
  1,在類進行初始化的時候,靜態代碼塊與靜態變量的賦值的順序是按照程序員編寫的順序執行的;
  2,在建立對象的<clint>(),是按照程序員編寫的代碼塊和成員變量的賦值的順序執行的。

下面的例子,建立後的對象的屬性a=22,類屬性TEST_STATIC=11.

public static class TestStaticInit{
        static{
            TEST_STATIC = 1;
        }
        public static int TEST_STATIC = 11;

        {
            a = 2;
        }
        public int a = 22;
    }

參考資料:

  1. 《深刻理解Java虛擬機》
相關文章
相關標籤/搜索