JVM原理之類加載的全過(guò)程
JVM原理-類加載過(guò)程
Java類加載過(guò)程
可以看作是將我們寫(xiě)的代碼(以class文件的形式)轉(zhuǎn)化為可以運(yùn)行的程序。
這過(guò)程分為幾個(gè)步驟:加載、鏈接、初始化、使用和卸載。
1.加載:找到并打開(kāi)書(shū)
- 過(guò)程:從書(shū)架上找到你要的書(shū),把它拿到桌子上,準(zhǔn)備閱讀。
- 對(duì)應(yīng)Java的過(guò)程:JVM從硬盤(pán)上找到編譯好的class文件(如Dog.class),然后把它讀入內(nèi)存里,生成一個(gè)Class對(duì)象。
- Class對(duì)象:這個(gè)對(duì)象包含了類的各種信息,比如類名、方法、字段等,相當(dāng)于一本被打開(kāi)的書(shū)。
2. 鏈接:檢查書(shū)的內(nèi)容和準(zhǔn)備好工具
鏈接階段包括驗(yàn)證、準(zhǔn)備和解析三個(gè)步驟:
驗(yàn)證:檢查書(shū)里的內(nèi)容是否有錯(cuò)誤。
- 對(duì)應(yīng)Java的過(guò)程:檢查class文件的格式和內(nèi)容是否合法,確保沒(méi)有語(yǔ)法錯(cuò)誤或其他問(wèn)題。
- 如果有錯(cuò)誤,程序會(huì)拋出異常,無(wú)法繼續(xù)運(yùn)行。
準(zhǔn)備:為靜態(tài)變量分配內(nèi)存并初始化為默認(rèn)值。
- 對(duì)應(yīng)Java的過(guò)程:靜態(tài)變量在這個(gè)階段被分配內(nèi)存,并初始化為默認(rèn)值。
- 例如,static int a;會(huì)被初始化為0。
解析(可選):把間接引用轉(zhuǎn)換為直接引用。
- 對(duì)應(yīng)Java的過(guò)程:把符號(hào)引用(指向類、方法、字段的字符串)
- 轉(zhuǎn)換為直接引用(內(nèi)存地址),方便后續(xù)快速訪問(wèn)。
3. 初始化:翻開(kāi)書(shū)并開(kāi)始閱讀
過(guò)程:正式開(kāi)始根據(jù)書(shū)里的內(nèi)容進(jìn)行設(shè)置和操作。
對(duì)應(yīng)Java的過(guò)程:執(zhí)行類的初始化,包括:
- 靜態(tài)變量的賦值:將靜態(tài)變量賦值為代碼中定義的值。例如,static int a = 10;,此時(shí)a會(huì)被設(shè)置為10。
- 靜態(tài)代碼塊的執(zhí)行:依次執(zhí)行靜態(tài)代碼塊中的代碼。靜態(tài)代碼塊可以用于復(fù)雜的初始化工作。
- 順序:靜態(tài)變量和靜態(tài)代碼塊的初始化按照它們?cè)诖a中出現(xiàn)的順序進(jìn)行。
4. 使用:開(kāi)始利用書(shū)中的信息
- 過(guò)程:根據(jù)書(shū)中的指導(dǎo)完成具體任務(wù)。
- 對(duì)應(yīng)Java的過(guò)程:實(shí)際使用類和對(duì)象,包括創(chuàng)建實(shí)例和調(diào)用方法。
- 對(duì)象創(chuàng)建:如new Dog(),JVM會(huì)在堆內(nèi)存中為Dog對(duì)象分配空間。
步驟:
- 分配內(nèi)存:為新對(duì)象分配內(nèi)存。
- 設(shè)置默認(rèn)值:對(duì)象的屬性被初始化為默認(rèn)值(如數(shù)字為0,對(duì)象引用為null)。
- 執(zhí)行初始化代碼:按照代碼中定義的順序?yàn)閷傩再x值。
- 執(zhí)行構(gòu)造函數(shù):運(yùn)行構(gòu)造函數(shù),進(jìn)行進(jìn)一步初始化和操作。
5. 卸載:書(shū)用完后放回書(shū)架
- 過(guò)程:書(shū)看完了,把它合上,放回書(shū)架,不再需要它了。
- 對(duì)應(yīng)Java的過(guò)程:當(dāng)類不再需要時(shí),JVM會(huì)把類從內(nèi)存中卸載,釋放占用的資源。
- 垃圾回收:JVM的垃圾回收機(jī)制會(huì)自動(dòng)檢測(cè)不再使用的類和對(duì)象,并回收它們占用的內(nèi)存。
對(duì)類初始化的5種情況
根據(jù)JVM規(guī)范,類初始化的情況有且只有以下5種:
- 創(chuàng)建類的實(shí)例:當(dāng)我們用new來(lái)創(chuàng)建類的對(duì)象時(shí),比如new Dog(),如果這個(gè)類還沒(méi)有被初始化,那么它必須先初始化才能創(chuàng)建對(duì)象。
- 調(diào)用類的靜態(tài)方法:比如Dog.bark(),靜態(tài)方法屬于類本身而不是某個(gè)對(duì)象,因此在調(diào)用時(shí),類必須先初始化。
- 訪問(wèn)類或接口的靜態(tài)變量:當(dāng)我們?cè)L問(wèn)類的靜態(tài)變量時(shí),比如Dog.age,這也會(huì)導(dǎo)致類的初始化。
- 使用Class.forName()方法:這種方法會(huì)強(qiáng)制初始化一個(gè)類。比如Class.forName("Dog")會(huì)讓Dog類被加載并初始化。
- 類加載器啟動(dòng)主類:當(dāng)我們運(yùn)行一個(gè)程序時(shí),比如執(zhí)行java DogMain,JVM會(huì)先初始化DogMain類并執(zhí)行它的main方法。
符號(hào)引用和直接引用的區(qū)別是什么?
- 符號(hào)引用:可以理解為一種間接的引用,它并不指向內(nèi)存中的具體位置。相當(dāng)于書(shū)里提到了某個(gè)章節(jié),但沒(méi)有告訴你具體在哪一頁(yè)。
- 直接引用:是內(nèi)存中的具體地址,也就是可以直接找到的目標(biāo)地址。相當(dāng)于書(shū)里直接標(biāo)明某個(gè)章節(jié)在第幾頁(yè)。
類變量和實(shí)例變量
類變量(靜態(tài)變量)
- 定義:使用static關(guān)鍵字修飾的變量。
- 歸屬:屬于類本身,而不是某個(gè)特定的對(duì)象。
- 共享性:所有實(shí)例共享同一個(gè)類變量。如果一個(gè)實(shí)例修改了類變量的值,其他實(shí)例也會(huì)看到這個(gè)變化。
- 生命周期:在類加載時(shí)被初始化,直到類卸載時(shí)被回收。其存儲(chǔ)在方法區(qū)(Method Area)。
- 訪問(wèn)方式:可以通過(guò)類名直接訪問(wèn),也可以通過(guò)實(shí)例訪問(wèn),但推薦使用類名進(jìn)行訪問(wèn)。
實(shí)例變量
- 定義:沒(méi)有使用static關(guān)鍵字修飾的變量。
- 歸屬:屬于類的每個(gè)實(shí)例,每個(gè)實(shí)例都有自己獨(dú)立的一份實(shí)例變量。
- 獨(dú)立性:每個(gè)實(shí)例的實(shí)例變量相互獨(dú)立,一個(gè)實(shí)例的實(shí)例變量變化不會(huì)影響其他實(shí)例的實(shí)例變量。
- 生命周期:在對(duì)象創(chuàng)建時(shí)被初始化,直到對(duì)象被垃圾回收時(shí)被回收。其存儲(chǔ)在堆內(nèi)存(Heap Memory)。
- 訪問(wèn)方式:只能通過(guò)對(duì)象實(shí)例來(lái)訪問(wèn),不能通過(guò)類名直接訪問(wèn)。
Class.forName()
Class.forName()的主要作用是 動(dòng)態(tài)加載類,尤其是在需要根據(jù)類名字符串來(lái)加載類的情況下(比如 JDBC 驅(qū)動(dòng)程序、反射等)。
這提供了一種靈活的方式,允許你在運(yùn)行時(shí)加載類,而不是在編譯時(shí)綁定類。
當(dāng)你調(diào)用這個(gè)方法時(shí),JVM 會(huì)嘗試根據(jù)你傳遞的類名(作為字符串)加載該類,并且會(huì)執(zhí)行該類的靜態(tài)代碼塊(如果有的話)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java String類簡(jiǎn)單用法實(shí)戰(zhàn)示例【字符串輸出、比較】
這篇文章主要介紹了Java String類簡(jiǎn)單用法,結(jié)合具體實(shí)例形式分析了Java使用String類實(shí)現(xiàn)字符串的輸出和比較功能相關(guān)操作技巧,需要的朋友可以參考下2019-07-07JAVA?ImageIO.read方法報(bào)錯(cuò)/無(wú)效問(wèn)題及解決
這篇文章主要介紹了JAVA?ImageIO.read方法報(bào)錯(cuò)/無(wú)效問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11詳解配置spring-boot-actuator時(shí)候遇到的一些小問(wèn)題
這篇文章主要介紹了詳解配置spring-boot-actuator時(shí)候遇到的一些小問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11sql于navicat中能運(yùn)行在mybatis中不能運(yùn)行的解決方案
這篇文章主要介紹了sql于navicat中能運(yùn)行在mybatis中不能運(yùn)行的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01java訪問(wèn)者模式的靜態(tài)動(dòng)態(tài)及偽動(dòng)態(tài)分派徹底理解
這篇文章主要為大家介紹了java訪問(wèn)者模式的靜態(tài)動(dòng)態(tài)及偽動(dòng)態(tài)分派徹底理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06Javaweb基礎(chǔ)入門(mén)requse原理與使用
Request對(duì)象的作用是與客戶端交互,收集客戶端的Form、Cookies、超鏈接,或者收集服務(wù)器端的環(huán)境變量,接下來(lái)本篇將詳細(xì)講述2021-11-11java 出現(xiàn)Zipexception 異常的解決辦法
這篇文章主要介紹了java 出現(xiàn)Zipexception 異常的解決辦法的相關(guān)資料,出現(xiàn) java.util.zip.ZipException: error in opening zip file 異常的原因及解決方法,需要的朋友可以參考下2017-08-08springboot + JPA 配置雙數(shù)據(jù)源實(shí)戰(zhàn)
這篇文章主要介紹了springboot + JPA 配置雙數(shù)據(jù)源實(shí)戰(zhàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09