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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

第二十二期:New一个对象的时候发生了什么?

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第二十二期:New一个对象的时候发生了什么? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如你所知,Java是一門面向對象的編程語言。我們平常在寫代碼的時候也是在不停的操作各種對象,那么當你在寫出User user = new User();這樣一行代碼的時候,JVM都做了些什么呢?

作者:湖人總冠軍

?一、引言

如你所知,Java是一門面向對象的編程語言。我們平常在寫代碼的時候也是在不停的操作各種對象,那么當你在寫出User user = new User();這樣一行代碼的時候,JVM都做了些什么呢?

二、了解對象

1、內存布局

在Hotspot虛擬機中一個對象的內存布局分為三個部分:對象頭、實例數據、對齊填充。

  • 對象頭又有兩部分的信息,第一部分是用于存儲對象自身的運行數據(HashCode、GC分代年齡、鎖狀態標志等)。另一部分是類型指針,指向它的類元數據,虛擬機通過這個指針確定這個對象是哪個類的實例(如果使用句柄池方式則不會有)。如果是數組還會有一個記錄數組長度的如下表所示:

Mark Word是一個非固定的數據結構以便在極小的空間內存儲盡量多的信息,它會根據對象的狀態復用自己的存儲空間。各狀態下的存儲內容如下表所示:

  • 實例數據部分是真正存儲的有效信息,就是在代碼中定義的各種類型的字段內容。無論是父類繼承下來的,還是在子類中的。
  • 對齊填充不是必須存在的,僅僅起著占位符的作用,因為HotSpot虛擬機要求對象的起始地址必須是8字節的整數倍。

2、對象的訪問

Java程序中我們操作一個對象是通過指向這個對象的引用。我們都知道對象存在堆中,這個引用存在虛擬機棧中。那么引用通過什么方式去定位堆中對象的位置呢?

  • 直接指針法(HotSpot實現):引用中直接存儲的就是堆中對象的地址。好處就是一次定位速度快,缺點是對象移動(GC時對象移動)引用本身需要修改。

  • 句柄法:Java堆中劃分出一部分作為句柄池,引用存儲的是對象的句柄地址,而句柄中包括了對象實例和類型的具體位置信息。好處是對象移動只會改變句柄中的實例數據指針,缺點是兩次定位。

三、創建對象流程

上面介紹了對象的基本信息,現在來講一講創建對象的流程:

  • 當虛擬機遇到一條new指令時,會去檢查這個指令的參數能否在常量池中定位到一個類的符號引用,并檢查代表的類是否已經被類加載器加載。如果沒有被加載那么必須先執行這個類的加載。
  • 類加載檢查通過后,虛擬機將為新對象分配內存,對象所需內存的大小在類加載后便可以確定。
  • 內存分配完成后,虛擬機需要將對象初始化為零值,保證對象的實例變量在代碼中不賦初始值就能直接使用。類變量在類加載的準備階段初始化為零值。
  • 對對象頭進行必要信息的設置,比如如何找到類的元數據信息、對象的HashCode、GC分代年齡等。
  • 經過上述操作,一個新的對象已經產生,但是方法還沒有執行,所有的字段都是零值。這時候需要執行方法(構造方法)把對象按照程序員的意愿進行初始化。類變量的初始化操作在類加載的初始化階段方法完成
  • 分配內存有兩種方式:

    • Java堆內存是規整的(使用標記整理或帶壓縮的垃圾收集器),使用一個指針指向空閑位置,分配內存既將指針移動與分配大小相等的距離
    • 內存不是規整的(使用標記清除的垃圾收集器),虛擬機維護一個可用內存塊列表,分配內存時從列表中找到一個足夠大的內存空間劃分給對象并更新可用內存列表。

    無法找到足夠的內存時會觸發一次GC

    分配內存時并發問題解決方案:

    • 對分配內存空間的動作進行同步操作---采用CAS失敗重試的方式保證更新操作的原子性。
    • 每個線程在堆中預先分配一塊小內存,稱為本地線程分配緩沖(Thread Local Allocation Buffer,TLAB),哪個線程要分配內存就在它的TLAB上分配,只有TLAB用完并分配新的TLAB時才需要同步鎖定。通過-XX:+/-UseTLAB參數來設定。

    四、創建對象指令重排序問題

  • A?a?=?new?A();?
  • new一個對象的簡單分解動作:

  • 分配對象的內存空間
  • 初始化對象
  • 設置引用指向分配的內存地址
  • 其中2、3兩步間會發生指令重排序,導致多線程時如果在初始化之前訪問對象則會出現問題,單例模式的雙重檢測鎖模式正是會存在這個問題。可以使用volatile來禁止指令重排序解決問題

    閱讀目錄(置頂)(長期更新計算機領域知識)

    閱讀目錄(置頂)(長期更新計算機領域知識)

    閱讀目錄(置頂)(長期科技領域知識)

    歌謠帶你看java面試題

    ?

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的第二十二期:New一个对象的时候发生了什么?的全部內容,希望文章能夠幫你解決所遇到的問題。

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