上一篇文章,介紹了虛擬機類加載的過程,那麼類加載好以後,虛擬機下一步該幹什麼呢。咱們知道java是面向對象的編程語言,因此對象能夠說是java'的靈魂,這篇文章咱們就來介紹java
虛擬機是如何建立對象、對象內存分配以及對象是如何使用的(訪問定位)。因爲各個虛擬機的實現不盡相同,因此這裏咱們以最經常使用的HotSpot虛擬機爲例來介紹。編程
對象在虛擬機中建立的步驟以下:數組
在HotSpot虛擬機裏,對象在堆內存中的存儲佈局能夠劃分爲三個部分:對象頭、實例數據和對其填充。編程語言
HotSpot虛擬機對象的對象頭部分包括兩類信息:函數
顧名思義,實例數據部分存儲的就是實例對象的相關信息了,即咱們在程序代碼裏面所定義的各類類型的字段內容,不管是從父類繼承下來的,仍是在子類中定義的字段都必須記錄起來。佈局
對象的第三部分是對齊填充,這並非必然存在的,也沒有特別的含義,它僅僅起着佔位符的做用。因爲HotSpot虛擬機的自動內存管理系統要求對象的起始地址必須是8字節的整數倍,因此線程
不足8的整數倍就須要補齊。指針
建立對象天然是爲了後續使用該對象,java虛擬機規範規定java程序經過虛擬機棧的reference來操做堆上的具體對象,各個虛擬機實現的訪問方式也不盡相同,主流的訪問方式主要使用句柄和直接指針兩種,code
咱們先來看經過句柄的方式訪問,以下圖:對象
經過句柄訪問,java堆中會將劃分出一塊內存來做句柄池,reference中存儲的就是對象的句柄地址,句柄中包含了對象實例數據以及類型數據的地址信息。而指針訪問的話,
reference中存儲的直接就是對象地址,對象實例中同時還須要存指向對象類型數據的指針。以下圖所示:
這兩種對象訪問方法各有優點,直接指針訪問方式,雖然訪問訪問速度快,可是垃圾回收的效率沒有句柄池的效率高。咱們經常使用的HotSpot是使用的直接指針的方式訪問對象。