对象实例化指针_JVM第三课:一文讲透对象的内存布局和访问方式
對象的內存布局和訪問定位
對象的實例化
對象的創建方式
new
Class的newInstance方法
Class> aClass = Class.forName("com.mu.ConstructorDemo");ConstructorDemo o = (ConstructorDemo)aClass.newInstance();
Constructor的newInstance方法,可以放參數,調用有參構造
Constructor constructor = ConstructorDemo.class.getConstructor();ConstructorDemo constructorDemo = constructor.newInstance();
Clone:不調用構造方法,當前類實現Cloneable接口
反序列化
創建對象的步驟
判斷對象對應的類是否加載,鏈接,初始化
虛擬機遇到一個new指令,首先去檢查這個指令的參數能否在Metaspace的常量池中定位到這個類的符號引用,并且檢查這個符號引用代表的類是否已經被加載,解析和初始化。
如果沒有,那么在雙親委派模式下,使用當前的類加載器,以ClassLoader+包名+類名為key進行查找對應的.class文件,如果沒有找到文件,則拋出ClassNotFoundException異常,如果找到,則進行類加載,并生成對應的Class類對象
為對象分配內存
首先計算對象占用空間大小,接著在堆中劃分一塊內存給新對象
如果實例成員變量是引用變量,僅分配引用變量即可,即4個字節大小
如果內存規整,使用指針碰撞
所有用過的內存在一邊,空閑的內存在另一邊,中間放著一個指針作為分界點的指示器,分配內存就僅僅把指針向空閑那邊挪動一段與對象大小相等的距離
有壓縮算法和整理功能的垃圾回收器,采用指針碰撞的方式分配內存
如果內存不規整,虛擬機維護一個列表,使用空閑列表分配(CMS垃圾收集器)
意思是虛擬機維護一個列表,記錄那些內存塊是可用的,再分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的內容,這種分配方式稱為“空閑列表”
處理并發安全問題
創建對象是非常頻繁的操作,虛擬機需要解決并發安全問題,兩種方式:
CAS(Compare And Swap)失敗重試,區域加鎖,保證指針更新操作的原子性
TLAB:本地線程緩沖區
初始化分配到的空間
內存分配結束,虛擬機將分配到的內存都初始化成零值(不包括對象頭),這一步保證了對象的實例字段在Java代碼中可以不用賦值就可以使用,程序訪問的都是這些字段的零值
設置對象頭
將對象的所屬類(類的元數據信息),對象的HashCode和對象的GC信息,鎖信息等存儲在對象的對象頭中,這一塊具體有JVM實現
執行init方法進行初始化
顯式賦值
對象的內存布局
對象頭
包含兩部分:
如果是數組,還需要記錄數組的長度
運行時元數據
哈希值,GC分代年齡,鎖狀態標志,線程持有的鎖,偏向線程ID,偏向時間戳
類型指針
指向類元數據,確定該對象所屬的類型
實例數據
它是對象真正存儲有效信息,包括程序代碼中定義的各種類型的字段(包括從父類繼承下來的和自己擁有的)
相同寬度的字段分配在一起(比如4個字節的數據在一起)
父類定義的變量會出現在子類之前
如果CompactFields參數為true(默認是true),子類的窄變量可能插入到父類的變量的間隙
對齊填充
僅僅起到占位符的作用
package com.mu;public class Customer {
public int id = 1001;
String name;
Account acct;
{
name = "匿名客戶";
}
public Customer(){
acct = new Account();
}
public static void main(String[] args) {
Customer cust = new Customer();
}
}
class Account{
}
實際分配圖如下:
對象的訪問定位:
訪問對象的方式有兩種:句柄和直接指針
句柄訪問
圖示:
有一個句柄池的概念,棧指向句柄池,句柄池保存對象的實例數據和對象的類型數據
優點是棧到句柄池的地址不會改變,reference存儲的是穩定的句柄地址,在對象被移動時(垃圾回收時)只會改變句柄中到實例數據的指針
直接指針(Hotspot采用直接指針)
reference存儲的就是對象的引用地址,最大的好處就是速度快,節省了一次指針定位的開銷,
總結
以上是生活随笔為你收集整理的对象实例化指针_JVM第三课:一文讲透对象的内存布局和访问方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx之为已安装nginx动态添加模
- 下一篇: 怎么用云服务器