自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java 對象到底是如何創(chuàng)建的?類加載機制是什么?對象的內存布局和訪問方式有哪些?

開發(fā) 前端
本章深入解析了類加載機制對對象創(chuàng)建的支持,探討了 JVM 的內存布局、訪問方式及分配策略。通過理解這些底層原理,開發(fā)者可以有效優(yōu)化代碼性能,并在內存問題排查中更加游刃有余。

對象是 Java 程序運行的核心,而 JVM 的對象管理機制直接影響程序的運行效率和內存管理能力。

在 Java 中,對象的創(chuàng)建過程離不開類的加載與初始化,因此理解類加載的原理和對象的內存布局,是掌握 JVM 性能優(yōu)化的關鍵。

本章基于類加載機制的深入解析,將詳細講解對象的創(chuàng)建、內存布局、訪問方式及分配策略,幫助你從理論到實踐全面掌握 JVM 對象管理的底層邏輯。

類加載機制概述

類加載是 Java 對象創(chuàng)建的基礎。

JVM 通過類加載器將 .class 文件中的二進制數(shù)據(jù)加載到內存,并將其轉化為 JVM 可以識別的運行時數(shù)據(jù)結構。以下是類加載的核心步驟:

類加載的七個階段

根據(jù)《Java 虛擬機規(guī)范》,類加載分為七個階段:

  1. 加載 (Loading) :將 .class 文件的二進制數(shù)據(jù)加載到內存,生成 Class 對象。
  2. 驗證 (Verification) :校驗 .class 文件的格式和內容是否符合規(guī)范,確保安全性。
  3. 準備 (Preparation) :為靜態(tài)變量分配內存并初始化默認值。
  4. 解析 (Resolution) :將符號引用替換為直接引用。
  5. 初始化 (Initialization) :執(zhí)行靜態(tài)變量的賦值及靜態(tài)代碼塊。
  6. 使用 (Using) :通過程序調用類的靜態(tài)變量或方法。
  7. 卸載 (Unloading) :釋放類占用的內存資源。

根據(jù) 《Java 虛擬機規(guī)范》 中的規(guī)定,類加載可以分為七個階段,分別為 加載 (Loading)、驗證 (Verification)、準備 (Preparation)、解析 (Resolution)、初始化 (Initialization)、使用 (Using) 和 卸載 (Unloading),其中 驗證、準備 和 解析 三個階段整體又稱為 鏈接 (Linking)。

圖片圖片

類加載就像從藍圖設計到建筑施工的過程:

  • 加載階段是獲取藍圖,確保設計的正確性;
  • 驗證階段是檢測建筑規(guī)范;
  • 準備與解析階段是施工基礎;
  • 初始化階段是建筑的竣工與驗收。

加載階段主要是使用 "類加載器" 將本地或者遠程網(wǎng)絡中的字節(jié)碼文件,通過讀字節(jié)流的方式加載到 Java 虛擬機內存中。在加載階段中 Java 虛擬機主要完成以下三件事情:

  • ① 通過一個類的全限定名稱來獲取定義此類的二進制字節(jié)流。
  • ② 將這個字節(jié)流所代表的靜態(tài)存儲結構轉化為方法區(qū)的運行時數(shù)據(jù)結構。
  • ③ 在內存中生成一個代表這個類的 java.lang.Class 對象,作為方法區(qū)中這個類的各種數(shù)據(jù)的訪問入口。

其中常用的類加載器有三種,分別是:

類加載器

描述

引導類加載器 BootstrapClassLoader

引導類加載器是使用 C++ 語言實現(xiàn)的,用于加載 Java 中的核心類庫的,一般會加載 JAVA_HOME 目錄下的 /jre/lib 文件夾下的 jar 和配置。


擴展類加載器 ExtClassLoader

擴展類加載器主要負責加載 Java 的擴展類庫,一般會加載 JAVA_HOME 目錄下的 /jre/lib/ext 文件夾下的 jar。

應用類加載器 AppClassLoader

應用類加載器是應用程序中默認的類加載器,可以加載 CLASSPATH 變量指定目錄下的 jar,并且一般情況下,我們編寫的 Java 應用的類,都是使用該類加載器完成加載的。

對象的內存分配與初始化

當類加載完成后,JVM 開始為新對象分配內存并完成初始化。

對象內存分配

確定分配區(qū)域

  • 堆分配:大部分對象分配在堆中。
  • 棧上分配:通過逃逸分析,局部且生命周期短的對象可分配在棧上。

分配方式

  • 指針碰撞:堆內存連續(xù),分配指針向空閑區(qū)域移動。
  • 空閑列表:堆內存不連續(xù),分配時通過列表找到合適的空閑塊。

對象初始化流程

  1. JVM 將分配的內存清零(不包括對象頭)。
  2. 調用對象的構造方法 <init>,完成實例變量初始化。

對象的內存布局

Java 對象在內存中的布局分為三部分:對象頭、實例數(shù)據(jù) 和 對齊填充。

圖片圖片

對象頭

對象頭包含以下內容:

  1. Mark Word ,存儲對象的哈希碼、GC 狀態(tài)、鎖標志等運行時信息。
  2. Class Pointer ,指向對象的類元信息,用于確定對象類型。
  3. 數(shù)組長度(僅數(shù)組對象) ,數(shù)組對象會額外存儲數(shù)組長度信息。

對象頭結構示意圖

圖片圖片

對象訪問方式

JVM 提供了兩種對象訪問模式:句柄池 和 直接指針。

句柄池

句柄:如果使用句柄訪問對象,JAVA 堆中將會劃分一塊內存作為句柄池,reference 中存儲的就是對象的句柄地址,句柄中包含對象實例數(shù)據(jù)與類型數(shù)據(jù)。

圖片圖片

優(yōu)點:對象內存地址變化時,只需更新句柄,而無需修改引用。

直接指針

如果使用直接指針訪問,則 reference 存儲對象地址。優(yōu)點:訪問速度快,少了一次間接訪問。

圖片圖片

對象內存分配策略

JVM 的內存分配策略與垃圾回收機制密切相關。以下是常見的內存分配方式:

  1. 棧上分配:通過逃逸分析,JVM 可將生命周期短的對象分配在棧上,避免 GC 的參與。
  2. 新生代與老年代分配:新生代分配,默認分配在 Eden 區(qū);Survivor 區(qū)用于存活對象的復制和晉升。生命周期較長或大對象直接分配到老年代。

對象主要分配在新生代的 Eden 區(qū)上,如果啟動了本地線程分配緩沖,將按線程優(yōu)先在 TLAB 上分配。少數(shù)情況下也可能直接分配在老年代中,分配的規(guī)則并不是百分之百固定的。

圖片圖片

大對象直接進入老年代

虛擬機提供了一個 -XX:PretenureSizeThreshold參數(shù),令大于這個設置值的對象直接在老年代分配,這樣做的目的是避免在 Eden 區(qū)和及兩個 Survivor 區(qū)之間發(fā)生大量的內存復制。

長期存活的對象將進入老年代

如果對象在 Eden 出生并經(jīng)過第一次 Minor GC 后仍然存活,并且能被 Survivor 容納的話,將被移動到 Survivor 空間中,并且對象年齡設為 1。

對象在 Survivor 空間中每“熬過”一次 Minor GC,年齡就增加 1 歲,當它的年齡到達一定程度(最大為 15 歲),就將會被晉升到老年代。

對象晉升老年代的年齡閾值,可以通過參數(shù) -XX:MaxTenuringThreshold 設置。

對象是否能夠晉升到老年代,也不全由-XX:MaxTenuringThreshold 參數(shù)控制,如果 Survivor 空間中相同年齡的所有對象大小總和大于 Survivor 空間的一半,年齡大于或等于該年齡的對象就可以直接進入老年代。

空間分配擔保

新生代在發(fā)生 Minor GC 之前,虛擬機會先檢查老年代最大可用的連續(xù)空間是否大于新生代所有對象之和(或者歷次晉升老年代對象的平均大?。?/p>

如果這個條件不成立,那么虛擬機將直接進行 Full GC 動作;如果這個條件成立,那么虛擬機就會進行一次 Minor GC 操作,但是這次 Minor GC 是有風險的,因為比較的值是平均值,可能出現(xiàn)極端的情況 —— 大量對象在 Minor GC 后還存活,這時就只好在失敗后重新發(fā)起一次 Full GC。

總結

本章深入解析了類加載機制對對象創(chuàng)建的支持,探討了 JVM 的內存布局、訪問方式及分配策略。

通過理解這些底層原理,開發(fā)者可以有效優(yōu)化代碼性能,并在內存問題排查中更加游刃有余。

責任編輯:武曉燕 來源: 碼哥跳動
相關推薦

2020-09-25 07:55:51

內存Java對象

2023-10-11 08:29:54

volatileJava原子性

2024-12-04 09:01:55

引導類加載器C++

2020-03-05 10:28:19

MySQLMRR磁盤讀

2022-10-08 00:00:00

Spring數(shù)據(jù)庫項目

2025-03-28 01:33:00

2019-07-24 08:34:35

Java對象數(shù)據(jù)結構

2022-07-06 08:05:52

Java對象JVM

2009-06-09 22:11:44

JavaScriptObject

2022-08-08 08:00:00

人工智能機器學習計算機應用

2024-02-22 08:00:00

SoraOpenAI

2018-05-03 15:03:09

內存虛擬化空間

2020-10-14 06:22:14

UWB技術感知

2010-11-01 01:25:36

Windows NT

2020-09-22 08:22:28

快充

2020-09-27 06:53:57

MavenCDNwrapper

2011-04-27 09:30:48

企業(yè)架構

2021-04-25 06:12:19

Java內存布局JVM

2012-09-03 09:58:09

2024-11-13 15:39:49

AIGCAI
點贊
收藏

51CTO技術棧公眾號