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

JVM優(yōu)化:JVM加載機(jī)制詳解——類裝載子系統(tǒng)

開發(fā) 前端
類的初始化階段是類加載過程的最后一個步驟, 之前介紹的幾個類加載的動作里, 除了在加載階段用戶應(yīng)用程序 可以通過自定義類加載器的方式局部參與外, 其余動作都完全由Java虛擬機(jī)來主導(dǎo)控 制。

一、類加載子系統(tǒng)介紹

1、類加載子系統(tǒng)負(fù)責(zé)從文件系統(tǒng)或是網(wǎng)絡(luò)中加載.class文件,class文件在文件開頭有特定的文件標(biāo)識。

2、把加載 后的class類信息存放于方法區(qū),除了類信息之外,方法區(qū)還會存放運(yùn)行時常量池信息,可能還包括字符串字面量和 數(shù)字常量(這部分常量信息是Class文件中常量池部分的內(nèi)存映射);

3、ClassLoader只負(fù)責(zé)class文件的加載,至于 它是否可以運(yùn)行,則由Execution Engine決定;

4、如果調(diào)用構(gòu)造器實(shí)例化對象,則該對象存放在堆區(qū);

二、類加載器ClassLoader角色

1. class file 存在于本地硬盤上,可以理解為設(shè)計師畫在紙上的模板,而最終這個模板在執(zhí)行的時候是要加載到 JVM當(dāng)中來根據(jù)這個文件實(shí)例化出n個一模一樣的實(shí)例。

2. class file 加載到JVM中,被稱為DNA元數(shù)據(jù)模板。

3. 在 .class文件 --> JVM --> 最終成為元數(shù)據(jù)模板,此過程就要一個運(yùn)輸工具(類裝載器Class Loader),扮演一 個快遞員的角色。

三、類加載的執(zhí)行過程

我們知道我們寫的程序經(jīng)過編譯后成為了.class文件,.class文件中描述了類的各種信息,最終都需要加載到虛擬機(jī) 之后才能運(yùn)行和使用。而虛擬機(jī)如何加載這些.class文件?.class文件的信息進(jìn)入到虛擬機(jī)后會發(fā)生什么變化?

類使用的7個階段

類從被加載到虛擬機(jī)內(nèi)存中開始,到卸載出內(nèi)存,它的整個生命周期包括:加載(Loading)、驗(yàn)證 (Verification)、準(zhǔn)備(Preparation)、解析(Resolution)、初始化(Initiallization)、使用(Using)和卸載 (Unloading)這7個階段。其中驗(yàn)證、準(zhǔn)備、解析3個部分統(tǒng)稱為連接(Linking),這七個階段的發(fā)生順序如下 圖:

圖中,加載、驗(yàn)證、準(zhǔn)備、初始化、卸載這5個階段的順序是確定的,類的加載過程必須按照這種順序按部就班地 開始,而解析階段不一定:它在某些情況下可以初始化階段之后在開始,這是為了支持Java語言的運(yùn)行時綁定(也 稱為動態(tài)綁定)。接下來講解加載、驗(yàn)證、準(zhǔn)備、解析、初始化五個步驟,這五個步驟組成了一個完整的類加載過 程。使用沒什么好說的,卸載屬于GC的工作 。

1、加載

加載是類加載的第一個階段。有兩種時機(jī)會觸發(fā)類加載:

1)預(yù)加載

虛擬機(jī)啟動時加載,加載的是JAVA_HOME/lib/下的rt.jar下的.class文件,這個jar包里面的內(nèi)容是程序運(yùn)行時非常常 常用到的,像java.lang.*、java.util.、java.io. 等等,因此隨著虛擬機(jī)一起加載。要證明這一點(diǎn)很簡單,寫一個空的 main函數(shù),設(shè)置虛擬機(jī)參數(shù)為"-XX:+TraceClassLoading"來獲取類加載信息,運(yùn)行一下:

2)運(yùn)行時加載

虛擬機(jī)在用到一個.class文件的時候,會先去內(nèi)存中查看一下這個.class文件有沒有被加載,如果沒有就會按照類的 全限定名來加載這個類。

那么,加載階段做了什么,其實(shí)加載階段做了有三件事情:

獲取.class文件的二進(jìn)制流

將類信息、靜態(tài)變量、字節(jié)碼、常量這些.class文件中的內(nèi)容放入方法區(qū)中

在內(nèi)存中生成一個代表這個.class文件的java.lang.Class對象,作為方法區(qū)這個類的各種數(shù)據(jù)的訪問入口。一般 這個Class是在堆里的,不過HotSpot虛擬機(jī)比較特殊,這個Class對象是放在方法區(qū)中的

虛擬機(jī)規(guī)范對這三點(diǎn)的要求并不具體,因此虛擬機(jī)實(shí)現(xiàn)與具體應(yīng)用的靈活度都是相當(dāng)大的。例如第一條,根本沒有 指明二進(jìn)制字節(jié)流要從哪里來、怎么來,因此單單就這一條,就能變出許多花樣來:

  •  從zip包中獲取,這就是以后jar、ear、war格式的基礎(chǔ)
  • 從網(wǎng)絡(luò)中獲取,典型應(yīng)用就是Applet
  • 運(yùn)行時計算生成,典型應(yīng)用就是動態(tài)代理技術(shù)
  •  由其他文件生成,典型應(yīng)用就是JSP,即由JSP生成對應(yīng)的.class文件
  • 從數(shù)據(jù)庫中讀取,這種場景比較少見

總而言之,在類加載整個過程中,這部分是對于開發(fā)者來說可控性最強(qiáng)的一個階段。

2、鏈接

鏈接包含三個步驟: 分別是 驗(yàn)證Verification , 準(zhǔn)備Preparation , 解析Resolution 三個過程

1)驗(yàn)證Verification

連接階段的第一步,這一階段的目的是為了確保.class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不 會危害虛擬機(jī)自身的安全。

Java語言本身是相對安全的語言(相對C/C++來說),但是前面說過,.class文件未必要從Java源碼編譯而來,可以 使用任何途徑產(chǎn)生,甚至包括用十六進(jìn)制編輯器直接編寫來產(chǎn)生.class文件。在字節(jié)碼語言層面上,Java代碼至少從 語義上是可以表達(dá)出來的。虛擬機(jī)如果不檢查輸入的字節(jié)流,對其完全信任的話,很可能會因?yàn)檩d入了有害的字節(jié) 流而導(dǎo)致系統(tǒng)崩潰,所以驗(yàn)證是虛擬機(jī)對自身保護(hù)的一項(xiàng)重要工作。

驗(yàn)證階段將做一下幾個工作,具體就不細(xì)講了,這是虛擬機(jī)實(shí)現(xiàn)層面的問題:

  • 文件格式驗(yàn)證
  • 元數(shù)據(jù)驗(yàn)證
  • 字節(jié)碼驗(yàn)證
  • 符號引用驗(yàn)證

2)準(zhǔn)備Preparation

準(zhǔn)備階段是正式為類變量分配內(nèi)存并設(shè)置其初始值的階段,這些變量所使用的內(nèi)存都將在方法區(qū)中分配。關(guān)于這 點(diǎn),有兩個地方注意一下:

  •  這時候進(jìn)行內(nèi)存分配的僅僅是類變量(被static修飾的變量),而不是實(shí)例變量,實(shí)例變量將會在對象實(shí)例化 的時候隨著對象一起分配在Java堆中
  •  這個階段賦初始值的變量指的是那些不被final修飾的static變量,比如"public static int value = 123",value在準(zhǔn) 備階段過后是0而不是123,給value賦值為123的動作將在初始化階段才進(jìn)行;比如"public static final int value = 123;"就不一樣了,在準(zhǔn)備階段,虛擬機(jī)就會給value賦值為123。

各個數(shù)據(jù)類型的零值如下表:

3、解析Resolution

解析階段是虛擬機(jī)將常量池內(nèi)的符號引用替換為直接引用的過程。來了解一下符號引用和直接引用有什么區(qū)別:

1)符號引用

符號引用是一種定義,可以是任何字面上的含義,而直接引用就是直接指向目標(biāo)的指針、相對偏移量。 這個其實(shí)是屬于編譯原理方面的概念,符號引用包括了下面三類常量: 類和接口的全限定名 字段的名稱和描述符 方法的名稱和描述符

2)直接引用

直接引用可以是直接指向目標(biāo)的指針、相對偏移量或是一個能間接定位到目標(biāo)的句柄。直接引用是和虛擬機(jī)實(shí)現(xiàn)的 內(nèi)存布局相關(guān)的,同一個符號引用在不同的虛擬機(jī)示例上翻譯出來的直接引用一般不會相同。如果有了直接引用, 那引用的目標(biāo)必定已經(jīng)存在在內(nèi)存中了。

解析階段負(fù)責(zé)把整個類激活,串成一個可以找到彼此的網(wǎng),過程不可謂不重要。那這個階段都做了哪些工作呢?大 體可以分為:

  • 類或接口的解析
  •  類方法解析
  • 接口方法解析
  • 字段解析

4、初始化

類的初始化階段是類加載過程的最后一個步驟, 之前介紹的幾個類加載的動作里, 除了在加載階段用戶應(yīng)用程序 可以通過自定義類加載器的方式局部參與外, 其余動作都完全由Java虛擬機(jī)來主導(dǎo)控 制。 直到初始化階段, Java 虛擬機(jī)才真正開始執(zhí)行類中編寫的Java程序代碼, 將主導(dǎo)權(quán)移交給應(yīng)用程序。

初始化階段就是執(zhí)行類構(gòu)造器()方法的過程。 ()并不是程序員在Java代碼中直接編寫 的方法, 它是Javac編譯器的 自動生成物,()方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態(tài)語句塊(static{}塊) 中的 語句合并產(chǎn) 生的, 編譯器收集的順序是由語句在源文件中出現(xiàn)的順序決定的, 靜態(tài)語句塊中只能訪問 到定義在靜態(tài)語句塊之 前的變量, 定義在它之后的變量, 在前面的靜態(tài)語句塊可以賦值, 但是不能訪 問。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2023-10-31 16:00:51

類加載機(jī)制Java

2020-05-12 22:24:44

JVM系統(tǒng)加載器

2024-12-02 09:01:23

Java虛擬機(jī)內(nèi)存

2017-09-20 08:07:32

java加載機(jī)制

2020-10-26 11:20:04

jvm類加載Java

2021-04-29 11:18:14

JVM加載機(jī)制

2017-03-08 10:30:43

JVMJava加載機(jī)制

2022-10-08 08:34:34

JVM加載機(jī)制代碼

2021-09-24 08:10:40

Java 語言 Java 基礎(chǔ)

2024-03-12 07:44:53

JVM雙親委托機(jī)制類加載器

2021-05-25 09:56:42

Jvm類加載機(jī)制Java

2021-02-28 11:58:33

JVM機(jī)制語言

2010-09-26 13:23:13

JVM內(nèi)存管理機(jī)制

2019-12-30 11:25:06

Jvm運(yùn)行java

2020-05-20 22:13:26

JVM加載機(jī)制虛擬機(jī)

2024-04-09 08:41:41

JVM類加載Java

2010-12-10 15:40:58

JVM內(nèi)存管理

2010-09-26 16:55:31

JVM學(xué)習(xí)筆記

2021-06-16 00:57:16

JVM加載機(jī)制

2024-03-08 08:26:25

類的加載Class文件Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號