「1. JVM的位置:」 ![]() JVM是運行在操作系統(tǒng)之上的虛擬機,跟硬件沒有直接交互。這也就體現(xiàn)了它跨平臺的優(yōu)越性。只要你這個操作系統(tǒng)能運行JVM,那么就可以運行java程序。 「2. JVM體系結構:」 下圖為JVM的體系結構,灰色的表示線程私有,且該區(qū)域不存在垃圾回收,橙色的表示線程共享,且存在垃圾回收。 ![]() 「3. 類加載器ClassLoader:」 負責加載class文件,class文件中文件開頭有特定的標識,隨便寫個txt改成class,jvm是不能加載的。classLoader的作用就是將class文件加載到內(nèi)存中,并將這些內(nèi)容轉換成方法區(qū)中的運行時數(shù)據(jù)結構。通過classLoader加載后,就會生成類的模板,之后new實例的時候,都是通過這個模板生成。類的模板就放在方法區(qū)。 「(1). 類加載器分為以下幾類:」
C++語言寫的,加載的是jre中的rt.jar。為什么我們可以直接用Object類,為什么能直接用ArrayList類?因為這些類都在rt.jar中,并且通過啟動類加載器加載到了內(nèi)存中。
java寫的,加載的是jre/lib/ext/*.jar。因為java編寫之初沒寫那么多功能,后來陸續(xù)加了一些功能,就被稱為擴展類,擴展類加載器就是用來加載這些類的。
加載用戶自己寫的類。比如我寫了一個Test類,就是靠應用類加載器去加載。
用戶可以繼承java.lang.ClassLoader類,實現(xiàn)自己的類加載器,定制加載方式。 「(2). 類加載器之間的關系:」
打印的結果是: 「得出結論」:
「(3). 雙親委派機制:」 別把這個想得有多難,可以借用一句話輔助理解:“我爸是李剛,有事找他”。應用類加載器要加載一個類的時候,它會先讓它的父親擴展類加載器去加載,同樣的,擴展類加載器又會讓它的父親啟動類加載器去加載。啟動類加載器如果沒加載到,就告訴擴展類加載器,擴展類加載器如果沒加載到,再告訴應用類加載器,這個時候才輪到應用類加載器加載。也就是說,孫子要辦事先找父親,父親又找爺爺,能不自己動手堅決不自動動手。 「(4). 沙箱安全:」 為什么要用雙親委派機制?看下面的例子:
我自己新建了一個java.lang包,寫了一個String類。運行卻發(fā)現(xiàn)報錯了: ![]() 我寫的String中明明就有main方法,它卻說沒有,這也驗證了雙親委派機制,說明加載的不是我自己寫的String類,而是rt.jar中的String類。用雙親委派機制,在類路徑相同的情況下,優(yōu)先加載java自帶的,這樣就可以保證java自帶的那些類的安全,保證它們不被污染,這就是沙箱安全。 「4. 本地方法棧:」 java有些方法底層是通過C語言實現(xiàn)的,這些方法棧java源碼中都沒有實現(xiàn),并且有native關鍵字修飾。比如線程的start方法, 「5. 程序計數(shù)器:」 也叫PC寄存器,其實就是一個指針。比如在循環(huán)、遞歸的時候,程序要如何知道跳出這層循環(huán)后應該執(zhí)行哪行代碼,遞歸的執(zhí)行是怎么個順序?這些都靠程序計數(shù)器來完成,它可以讓程序知道接下來該執(zhí)行什么。 掃描二維碼 |
|