跟我一起學JVM(二)——Java對象的幕後

今天的學習內容爲Java對象的創建,內存分配以及訪問。

我們都知道在Java程序中使用new關鍵字能夠爲我們創建一個對象實例,並且能按照我們的需要去進行一系列的對象初始化工作,但是很少有人願意探究這個對象構建背後的過程。本文第一部分就是詳細解讀一個對象是如何被創造的。

(一)對象的創建

爲了更好的理解,對象的創建過程將通過流程圖來展示:
在這裏插入圖片描述
我們平時只會使用new,而一個new背後其實是這樣的工作機制,這是值得我們深入學習的。

(二)對象的內存分配

對象內存分配流程圖
在這裏插入圖片描述
我們可以根據實際的研發需要設置改變Java虛擬機的相關參數,比如佔空間多少的對象可以被定義爲大對象,新生代的最大年齡是多少等等。具體的內存分配細節又可如下展開:

  1. 在Eden先進行分配,若空間不夠則進行Minor GC(指新生代中的GC)
  2. 大對象(長字符串以及數組等)直接進入老年代,因爲對象佔用空間大,新生代空間少,並且新生代採用的複製算法對於大對象效率低下。
  3. 長期存活的對象將進入老年代
    如何判斷一個對象屬於長期存活?使用對象年齡計數器,經過MinorGC並存活的對象將被移動到survivor中,並且對象年齡爲1,對象在survivor中每安全度過一次Minor GC,年齡就增加1,到一定年齡後(默認15歲)則進入到老年代中。
    動態對象年齡的判定
  4. 如果survivor空間中相同年齡的所有對象大小總和大於survivor的一半,年齡大於或等於該年齡的對象就可以直接進入老年代了,不需要一定達到默認值15歲才進入。
  5. 空間分配擔保,發生Minor GC之前。虛擬機會優先檢查老年代最大可用連續空間是否大於新生代所有對象的總空間,如果條件成立,則Minor GC是安全的,否則將查看HandlePromotionFailure設置值是否允許擔保失敗。每次都是採用一次垃圾回收後能晉升到老年代對象容量的平均大小值作爲經驗值,與老年代的剩餘空間進行比較,來確認是否進行Full GC(發生在老年代的GC,速度比Minor GC 慢10倍)。

(三)對象的訪問途徑

  1. 在Java堆設立句柄池和實例池,句柄池用來存儲指向實例池和方法區對象類型數據的指針
  2. 採用直接指針方式,Java堆存放對象實例數據,在對象實例數據中存放到對象類型數據的指針

注意:直接指針訪問速度更快,但是需要額外的空間存儲對象類型數據指針。

對象的背後蘊藏着計算機科學家們對於內存優化的極致追求,這章知識也是爲後面的垃圾收集算法與垃圾收集器打好基礎。

預告:下一期的學習內容爲垃圾收集算法與垃圾收集器

喜歡的話請關注點贊轉發三連哦~


Instagram: https://www.instagram.com/barrywzc/
Twitter: https://twitter.com/BarryWa34098316
Bilibili: https://space.bilibili.com/473161964
GitHub: https://github.com/wzcwzcwzc
Patreon: https://www.patreon.com/wzcspace
WeChat: wzcspace


Please leave a LIKE and SUBSCRIBE for more content!
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章