JVM學習記錄-類加載的過程

類的整個生命周期的7個階段是:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸載(Unloading)。

類加載的全過程主要包括:加載、驗證、準備、解析、初始化這5個階段的內容。

加載

加載是類加載過程的一個階段, 在加載階段JVM需要完成以下3件事情:

  1. 通過一個類的全限定明來獲取定義此類的二進制字節流。
  2. 將這個字節流所代表的靜態存儲結構轉化為方法區運行時數據結構。
  3. 在內存中生成一個代表這個類的java.lang.Class對象,作為方法區這個類的各種數據訪問入口。

加載階段(準確地說,是加載階段獲取類的二進制字節流的動作)是整個類加載過程中開發人員可控性最強的,因為加載階段既可以使用系統提供的引導類加載器完成,又可以由用戶自定義的二類加載器去完成,開發人員可以通過定義自己的類加載器區控制字節流的獲取方式。

加載階段完成后,虛擬機外部的二進制字節流就按照虛擬機所需的格式存儲在方法區中,方法區中的數據存儲格式由虛擬機的實現自行定義,虛擬機規范未規定此區域的具體數據結構。然后再內存中實例化一個java.lang.Class類的對象(這個對象,并沒有要求必須是在Java堆中,就HotSpot而言,Class對象比較特殊,雖然是對象,但是是存放在方法區中的),這個對象將作為程序訪問方法區中的這些類型數據的外部接口。

加載階段與連接階段的部分內容(如一部分字節碼文件格式驗證東西)是交叉進行的,但是這兩個階段的開始時間仍然保持著固定的 先后順序。

驗證

?驗證是連接階段的第一步,這一階段的目的是為了確保Class文件的字節流中包含的信息符合當前虛擬機的要求,并且不會危害虛擬機自身的安全。驗證階段是非常重要的,這個階段是否嚴謹,直接決定了Java虛擬機是否能承受惡意代碼的攻擊,它大致上會完成4個階段的檢驗工作:文件格式驗證、元數據驗證、字節碼驗證、符號引用驗證。

文件格式驗證

這一階段主要驗證字節流是否符合Class文件格式的規范,并且能被當前版本的虛擬機處理。

驗證內容包括:是否以魔數0xCAFEBABE開頭,主次版本號是否在當前虛擬機處理范圍之內,常量池的常量是否有不被支持的常量類型,指向常量的各種索引值是否有指向不存在的常量或不符合類型的常量,CONSTANT_Utf8_info型的常量中是否有不符合UTF8編碼的數據,Class文件中各個部分及文件本身是否有被刪除的或附近的其他信息等等。

元數據驗證

第二階段主要是對類的元數據信息進行語義校驗,保證不存在不符合Java語言規范的元數據信息。

驗證內容包括:當前類是否有父類(除了Object類之外,所有類都該有父類),當前類的父類是否繼承了不被允許繼承的類(被final修飾的類),如果當前類不是抽象類,是否實現了其父類或接口之中要求實現的所有方法,類中的字段、方法是否與父類產生矛盾(如覆蓋了父類的final字段等)等等。

字節碼驗證

第三階段是整個驗證過程中最復雜的一個階段,主要目的是通過數據流和控制流分析,確定程序語義是合法的、符合邏輯的。

驗證內容包括:保證任意時刻操作數棧的數據類型與指令代碼序列都能配合工作,例如:保證不會出現在操作棧放置了一個int類型的數據,使用時卻按long類型來加載如本地變量表中。保證跳轉指令不會跳轉到方法體以為的字節碼指令上。保證方法體上的類型轉換是有效的,例如:可以把一個子類對象賦值給父類數據類型,但是不能把父類對象賦值給子類數據類型。

符號引用驗證

最后一個階段的校驗發生在虛擬機將符號引用轉化為直接引用的時候,這個轉化動作發生在解析階段。符號引用驗證可以看做是對類自身以外的信息進行匹配校驗。

驗證內容包括:符號引用通過字符串描述的全限定明是否能找到對應的類。在指定類中是否存在符合方法的字段描述符以及簡單名稱所描述的方法和字段。符號引用中的類、字段、方法的訪問性是否可以被當前類訪問等等。

準備

準備階段是正式為類變量分配內存并設置類變量初始值的階段,這些變量所使用的內存都將在方法區中進行分配。這個階段分配內存的僅僅是類變量不包括實例變量。實例變量實在對象實例化的時候分配在堆內存中的,還有就是這里給類變量設置的初始值“通常情況下”下是數據類型的零值,例如:

public static int value = 666;

?這個變量value的值在準備階段被設置的初始值為0而不是666,因為此時尚未開始執行任何Java方法,而把value賦值為666的putstatic指令是程序編譯后,存放于類構造器<clinit>()方法之中,所以把value賦值為666的動作將在初始化階段才會執行。

上面說到在“通常情況”下初始值是零值,在非“通常情況”下也就是類字段屬性中存在常量屬性的時候,那么在準備階段類變量就會被初始化為常量屬性所指定的值。

public static final int value = 666;

編譯時Javac將會生成常量屬性,在準備階段虛擬機就會根據常量屬性的設置將value賦值為666;

解析

解析階段是虛擬機將常量池內的符號引用替換為直接引用的過程。

符號引用(Symbolic References):符號引用以一組符號來描述所引用的目標,符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標即可。符號引用與虛擬機實現的內存布局無關,引用目標并不一定已經加載到內存中。

直接引用(Direct References):直接引用可以是直接指向目標的指針、相對偏移量或是一個能間接定位到目標的句柄。直接引用是和虛擬機實現內存布局相關的,同一個符號引用在不同虛擬機實例上翻譯出來的直接引用一般不會相同。如果有直接引用,那引用的目標必定已經在內存中存在。

解析動作主要針對類或接口、字段、類方法、接口方法、方法類型、方法句柄和調用點限定符,這7類符號引用,分別對應于常量池的CONSTANT_Class_info、CONSTANT_Fieldref_info、CONSTANT_MethodHandle_info和CONSTANT_InvokeDynamic_info 這7中常量類型。

初始化

類初始化階段是類加載過程的最后一步,前面的類加載過程中,除了在加載階段用戶應用程序可以通過自定義類加載器參與之外,其余動作完全由虛擬機主導和控制。在準備階段,變量已經賦過一次系統初始零值了,而在初始化階段,是通過程序制定的主觀計劃去初始化類變量和其他資源,也就是執行類構造器<clinit>()方法的過程。在上一篇“類的加載時機”中已經介紹過了,有5中情況會出發類初始化,下面介紹的是在<clinit>()方法執行過程中一些可能會影響程序運行行為的特點和細節。

  • <clinit>()方法是由編譯器自動收集類中的所有類變量賦值動作和靜態語句塊(static{})中的語句合并產生的,編譯器收集順序室友語句在源文件中出現的豎線所決定的,靜態語句塊中只能訪問到定義在靜態語句塊之前的變量,定義在它之后的變量,在前面靜態語句塊可以賦值,但是不能訪問。
  • <clinit>()方法與類的構造函數不同,它不需要顯示的調用父類構造器,所以虛擬機中第一個被執行的<clinit>()方法的類肯定是java.lang.Object。
  • 由于父類的<clinit>()方法先執行,也就意味著福利中定義的靜態語句塊要由于子類的變量賦值操作。
  • <clinit>()方法對于類或接口來說并不是必需的,如果一個類中沒有靜態語句塊,也沒有對變量的賦值操作,那么編譯器可以不為這個類生產<clinit>()方法。
  • 接口中不能使用靜態語句塊,但仍然有變量初始化的賦值操作,因此接口和類一樣都會生成<clinit>()方法。接口中只有在使用父接口的時候才會初始化父接口(上一篇已經講解過)。
  • 虛擬機會保證一個類的<clinit>()方法在多線程的環境中被正確地枷鎖、同步,如果多個線程同時去初始化一個類,那么只會有一個線程區執行這個類的<clinit>()方法,其他線程都需要阻塞等待,直到活動線程<clinit>()方法

?

轉載于:https://www.cnblogs.com/jimoer/p/9091315.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280222.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280222.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280222.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用 Azure CLI 將 IaaS 資源從經典部署模型遷移到 Azure Resource Manager 部署模型

以下步驟演示如何使用 Azure 命令行接口 (CLI) 命令將基礎結構即服務 (IaaS) 資源從經典部署模型遷移到 Azure Resource Manager 部署模型。 本文中的操作需要 Azure CLI。 Note 此處描述的所有操作都是冪等的。 如果你遇到功能不受支持或配置錯誤以外的問題&#xff0c;建議你…

c++的進制轉換函數

https://blog.csdn.net/u010003835/article/details/47665847https://blog.csdn.net/vir_lee/article/details/80645066strtol函數&#xff1a;用于由十進制轉化到2~36的其他進制。函數原型為&#xff1a;long int strtol(const char *nptr,char **endptr,int base); 還應該注意…

黑蘋果不能imessage_如何修復iMessage在iOS 10中不顯示消息效果

黑蘋果不能imessageiMessage got a huge update in iOS 10, adding things like third-party app integration, rich links, and a number of fun graphical effects for messages. If you’re seeing messages that say something like “(sent with Invisible Ink)” instead…

MyBatisPlus怎么忽略映射字段

TableField(exist false)&#xff1a;表示該屬性不為數據庫表字段&#xff0c;但又是必須使用的。 TableField(exist true)&#xff1a;表示該屬性為數據庫表字段。 Mybatis-Plus 插件有這個功能&#xff0c;可以看一下 TableName&#xff1a;數據庫表相關 TableId&#xff1…

從技術總監到開源社區運營:過去兩年,我都做了點啥?

這是頭哥侃碼的第267篇原創今天&#xff0c;這是我離開前公司的第 7 天。相信有不少吃瓜群眾都很好奇&#xff0c;你這些天都在干啥&#xff1f;是不是蓬萊樂逍遙&#xff0c;過上了那悠閑的神仙日子&#xff1f;還是趁著疫情管控逐漸放開&#xff0c;和家人一起去深山老林里吸…

查看模擬器使用端口_為什么我們仍然使用模擬音頻端口?

查看模擬器使用端口When leaks about what the chassis of the iPhone 7 might look like hit headlines earlier this week, technology columnists and industry analysts jumped on the chance to report that Apple’s next device may finally ditch its 3.5mm audio port…

ServletContextListener在Springboot中的使用

ServletContextListener是servlet容器中的一個API接口, 它用來監聽ServletContext的生命周期&#xff0c;也就是相當于用來監聽Web應用的生命周期。今天我們就來說說如何在Springboot 1.5.2這個輕量型框架中如何使用它。 其實配置ServletContextListener與其它Filter, Listener…

《ASP.NET Core 6框架揭秘》實例演示[34]:緩存整個響應內容

我們利用ASP.NET開發的大部分API都是為了對外提供資源&#xff0c;對于不易變化的資源內容&#xff0c;針對某個維度對其實施緩存可以很好地提供應用的性能。《內存緩存與分布式緩存的使用》介紹的兩種緩存框架&#xff08;本地內存緩存和分布式緩存&#xff09;為我們提供了簡…

常見端口介紹

Win常用端口 TCP端口&#xff08;靜態端口&#xff09;TCP 0 ReservedTCP 1TCP Port Service MultiplexerTCP 2DeathTCP 5Remote Job Entry,yoyoTCP 7EchoTCP 11SkunTCP 12BomberTCP 16SkunTCP 17SkunTCP 18消息傳輸協議&#xff0c;skunTCP 19SkunTCP 20FTP Data,Amanda TCP 2…

如何更改Windows 10鎖定屏幕超時

By default, Windows 10’s lock screen times out and switches off your monitor after one minute. If you’d like it to stick around longer than that–say, if you have background picture you like looking at or you enjoy having Cortana handy–there’s a simple…

ios 開發賬號 退出協作_如何在iOS 10中的Notes上進行協作

ios 開發賬號 退出協作iOS’ Notes app provides a convenient way to remember the great ideas you come up with and all the things you have to do. The app has evolved over the years, and iOS 10 adds even more features–including collaboration. iOS的Notes應用程…

poj 1182

食物鏈Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 86494 Accepted: 25887Description 動物王國中有三類動物A,B,C&#xff0c;這三類動物的食物鏈構成了有趣的環形。A吃B&#xff0c; B吃C&#xff0c;C吃A。 現有N個動物&#xff0c;以1&#xff0d;N編號。每…

條款6:若不想使用編譯器自動生成的函數,就該明確拒絕

如果自己定義的類中并不需要copy assignment操作符或者copy構造函數&#xff0c;為了避免編譯器自動生成因為編譯器自動生成的沒什么用&#xff0c;一般是按照順序進行賦值或者拷貝&#xff0c;對于有對象內含有指針的話可能會出現一些問題可以在private中聲明&#xff08;并不…

為什么Android Geeks購買Nexus設備

The Galaxy S III is the highest-selling Android phone, but much of the geeky buzz is around the Nexus 4 – and the Galaxy Nexus before it. Nexus devices are special because they don’t have some of Android’s biggest problems. Galaxy S III是最暢銷的Android…

你的知識死角不能否定你的技術能力

有些事情你不知道&#xff0c;但你一定能解決。 有些人通過我賬號資料里的微信加我&#xff0c;然后問我一些所謂“怎么辦”的問題&#xff0c;不是我不告訴你&#xff0c;而是我確實不知道。我確實有很高的title&#xff0c;也確實有很多的技術積累&#xff0c;但我并沒有達到…

算法練習(十二)

The Suspects Description 嚴重急性呼吸系統綜合癥( SARS), 一種原因不明的非典型性肺炎,從2003年3月中旬開始被認為是全球威脅。為了減少傳播給別人的機會, 最好的策略是隔離可能的患者。 在Not-Spreading-Your-Sickness大學( NSYSU), 有許多學生團體。同一組的學生經常彼此相…

day4----函數-閉包-裝飾器

day4----函數-閉包-裝飾器 本文檔內容&#xff1a; 1 python中三種名稱空間和作用域 2 函數的使用 3 閉包 4 裝飾器 一 python中三種名稱空間和作用域 1.1名稱空間&#xff1a; 當程序運行時&#xff0c;代碼從上至下依次執行&#xff0c;它會將變量與值得關系存儲在一個空間中…

濾波器和均衡器有什么區別_什么是均衡器,它如何工作?

濾波器和均衡器有什么區別It’s in your car, home theater system, phone, and audio player but it doesn’t have an instruction manual. It’s an equalizer, and with a little know-how you can tweak your audio and fall in love with it all over again. 它在您的汽車…

網絡視頻監控與人臉識別

明天又要去面試了&#xff0c;趁次機會也將以前做的東西總結一下&#xff0c;為以后理解提供方便&#xff0c;也再加深下印象。 網絡視頻監控與人臉識別主要由三個程序組成&#xff1a;1、視頻采集與傳輸程序&#xff1b;2、接受與顯示程序&#xff1b;3、人臉識別程序。下面就…

esxi.主機配置上聯端口_為什么現代的電腦機箱仍然具有USB 2.0端口?

esxi.主機配置上聯端口With USB 3.0 becoming more prevalent with each passing year now, you may have found yourself wondering why modern computers still have USB 2.0 ports built into them. With that in mind, today’s SuperUser Q&A post has the answers to…