日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JVM_04 对象的实例化+内存布局+访问定位+直接内存

發布時間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM_04 对象的实例化+内存布局+访问定位+直接内存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、前言:

  • (1).new 最常見的方式 | 變形1 : Xxx的靜態方法 | 變形2 : XxBuilder/XxoxFactory的靜態方法
  • (2).Class的newInstance():反射的方式,只能調用空參的構造器,權限必須是public
  • (3).Constructor的newInstance(Xxx):反射的方式,可以調用空參、帶參的構造器,權限沒有要求
  • (4).使用clone() :不調用任何構造器,當前類需要實現Cloneable接口,實現clone()
  • (5).使用反序列化:從文件中、從網絡中獲取一個對象的二進制流
  • (6).第三方庫Objenesis

二、 對象的實例化 掌握

  • 判斷對象對應的類是否加載、鏈接、初始化
    (虛擬機遇到一條new指令,首先去檢查這個指令的參數能否在Metaspace的常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否已經被加載、解析和初始化。( 即判斷類元信息是否存在)。如果沒有,那么在雙親委派模式下,使用當前類加載器以ClassLoader+包名+類名為Key進行查找對應的.class文件。如果沒有找到文件,則拋出ClassNotFoundException異常,如果找到,則進行類加載,并生成對應的Class類對象)

  • 為對象分配內存:首先計算對象占用空間大小,接著在堆中劃分一塊內存給新對象。 如果實例成員變量是引用變量,僅分配引用變量空間即可,即4個字節大小
    (byte、int、float、引用數據類型4個字節大小 | double、long 占八個字節)

    • 如果內存規整,使用指針碰撞
      如果內存是規整的,那么虛擬機將采用的是指針碰撞法(BumpThePointer)來為對象分配內存。意思是所有用過的內存在一邊,空閑的內存在另外一邊,中間放著一個指針作為分界點的指示器,分配內存就僅僅是把指針向空閑那邊挪動一段與對象大小相等的距離罷了。如果垃圾收集器選擇的是Serial、ParNew這種基于壓縮算法的,虛擬機采用這種分配方式。一般使用帶有compact
      (整理)過程的收集器時,使用指針碰撞。 如果內存不規整,虛擬機需要維護一個列表,使用空閑列表分配(CMS)
    • 如果內存不是規整的,已使用的內存和未使用的內存相互交錯,那么虛擬機將采用的是空閑列表法來為對象分配內存。意思是虛擬機維護了一個列表,記錄上哪些內存塊是可用的,再分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的內容。這種分配方式成為“空閑列表(Free List)
    • 說明:選擇哪種分配方式由Java堆是否規整決定,而Java堆是否規整又由所采用的垃圾收集器是否帶有壓縮整理功能決定。
  • 處理并發安全問題
  • (在分配內存空間時,另外一個問題是及時保證new對象時候的線程安全性:創建對象是非常頻繁的操作,虛擬機需要解決并發問題。虛擬機采用了兩種方式解決并發問題:)

    • CAS ( Compare And Swap )失敗重試、區域加鎖:保證指針更新操作的原子性
    • TLAB把內存分配的動作按照線程劃分在不同的空間之中進行,即每個線程在Java堆中預先分配一小塊內存,稱為本地線程分配緩沖區,(TLAB,Thread Local Allocation Buffer) 虛擬機是否使用TLAB,可以通過一XX:+/一UseTLAB參數來 設定
  • 初始化分配到的空間:賦予默認的初始化值;比如int=0| boolean=false(默認的值)

  • 設置對象的對象頭:將對象的所屬類(即類的元數據信息)、對象的HashCode和對象的GC信息、鎖信息等數據存儲在對象的對象頭中。這個過程的具體設置方式取決于JVM實現。

  • 執行init方法進行初始化(進行賦值的處理)
    (在Java程序的視角看來,初始化才正式開始。初始化成員變量,執行實例化代碼塊,調用類的構造方法,并把堆內對象的首地址賦值給引用變量。
    因此一般來說(由字節碼中是否跟隨有invokespecial指令所決定),new指令之 后會接著就是執行方法,把對象按照程序員的意愿進行初始化,這樣一個真正可用的對象才算完全創建出來。)

  • ⑦. 代碼展示

    /*** 測試對象實例化的過程* ① 加載類元信息 - ② 為對象分配內存 - ③ 處理并發問題 - ④ 屬性的默認初始化(零值初始化)* - ⑤ 設置對象頭的信息 - ⑥ 屬性的顯式初始化、代碼塊中初始化、構造器中初始化** 給對象的屬性賦值的操作:* ① 屬性的默認初始化 - ② 顯式初始化 / ③ 代碼塊中初始化 - ④ 構造器中初始化* */ public class Customer{int id = 1001;String name;Account acct;{name = "匿名客戶";}public Customer(){acct = new Account();}}class Account{}

    三、對象的內存布局

  • 對象頭(Header)
    對象頭包含兩部分:(棧中的地址值就是一個哈希值) 掌握
    • 運行時元數據 (哈希值( HashCode )、GC分代年齡、鎖狀態標志、線程持有的鎖、偏向線程ID、偏向時間戳)
    • 類型指針:指向類元數據的InstanceKlass,確定該對象所屬的類型
    • 說明:如果是數組,還需記錄數組的長度
  • 實例數據(Instance Data)
    • 說明:它是對象真正存儲的有效信息,包括程序代碼中定義的各種類型的字段(包括從父類繼承下來的和本身擁有的字段) 規則:
    • 相同寬度的字段總被分配在一起
    • 父類中定義的變量會出現在子類之前
    • 如果CompactFields參數為true(默認為true),子類的窄變量可能插入到父類變量的空隙
  • 對齊填充(Padding)
  • ①. 不是必須的,也沒特別含義,僅僅起到占位符作用

    ②. 解釋如下圖:

  • 總結
    ①. 代碼演示
  • public class CustomerTest {public static void main(String[] args) {Customer cust = new Customer();} }

    ②. 圖解👆代碼

    四、對象的訪問定位

    前言:

    JVM是如何通過棧幀中的對象引|用訪問到其內部的對象實例的呢?-> 定位,通過棧上reference訪問

  • 句柄訪問

  • 直接指針(HotSpot采用)

  • 五、直接內存(Direct Memory) 了解

  • 不是虛擬機運行時數據區的一部分,也不是《Java虛擬機規范》中定義的內存區域

  • 直接內存是Java堆外的、直接向系統申請的內存區間

  • 代碼演示:

  • /*** IO NIO (New IO / Non-Blocking IO)* byte[] / char[] Buffer* Stream Channel** 查看直接內存的占用與釋放*/ public class BufferTest {private static final int BUFFER = 1024 * 1024 * 1024;//1GBpublic static void main(String[] args){//直接分配本地內存空間ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);System.out.println("直接內存分配完畢,請求指示!");Scanner scanner = new Scanner(System.in);scanner.next();System.out.println("直接內存開始釋放!");byteBuffer = null;System.gc();scanner.next();} }
  • 來源于NIO,通過存在堆中的DirectByteBuffer操作Native內存
  • 通常,訪問直接內存的速度會優于Java堆。即讀寫性能高

  • 直接內存大小可以通過MaxDirectMemorySize設置,如果不指定,默認與堆的最大值一Xmx參數值一致

  • ⑦. 簡單理解: java process memory = java heap + native memory

    總結

    以上是生活随笔為你收集整理的JVM_04 对象的实例化+内存布局+访问定位+直接内存的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。