[TOC]
Classloader 和 Execution Engine
classloader負(fù)責(zé)加載class文件,class文件在文件開頭有特定的文件標(biāo)示夹姥,并且ClassLoader只負(fù)責(zé)class文件的加載曾沈,至于它是否可以運行,則由Execution Engine決定
加載方式: 雙親委派模型
虛擬機自帶的加載器
啟動類加載器(Bootstrap)C++
擴展類加載器(Extension)Java
-
應(yīng)用程序類加載器(AppClassLoader)Java
也叫系統(tǒng)類加載器惧浴,加載當(dāng)前應(yīng)用的classpath的所有類
用戶自定義加載器
- Java.lang.ClassLoader的子類,用戶可以定制類的加載方式
意義: 防止內(nèi)存中出現(xiàn)多份同樣的字節(jié)碼,不同的classloader 加載用一個類實際上是不相同的奕剃。
tk.mybatis 某個版本在Spring Boot2.0 中使用就遇到過, Spring Boot2.0 使用 devtools時啟用了另外的一個classloader衷旅,導(dǎo)致scan的通用mapper類不一樣,報Cannot cast x.y.Z to x.y.Z
https://github.com/abel533/mapper-cast-exception 也是和大牛的一次接觸纵朋,遠(yuǎn)程給解決的
Execution Engine執(zhí)行引擎負(fù)責(zé)解釋命令柿顶,提交操作系統(tǒng)執(zhí)行
運行時數(shù)據(jù)區(qū)域
本地方法棧
它的具體做法是Native Method Stack中登記native方法,在Execution Engine 執(zhí)行時加載本地方法庫
程序計數(shù)器
每個線程都有一個程序計數(shù)器操软,是線程私有的,就是一個指針嘁锯,指向方法區(qū)中的方法字節(jié)碼(用來存儲指向下一條指令的地址,也即將要執(zhí)行的指令代碼),由執(zhí)行引擎讀取下一條指令聂薪,是一個非常小的內(nèi)存空間家乘,幾乎可以忽略不記。
方法區(qū)(Method Area)
方法區(qū)是被所有線程共享藏澳,所有字段和方法字節(jié)碼仁锯,以及一些特殊方法如構(gòu)造函數(shù),接口代碼也在此定義笆载。簡單說扑馁,所有定義的方法的信息都保存在該區(qū)域涯呻,此區(qū)屬于共享區(qū)間。
靜態(tài)變量+常量+類信息(構(gòu)造方法/接口定義)+運行時常量池存在方法區(qū)中
Java 棧(Java stack)
棧也叫棧內(nèi)存腻要,主管Java程序的運行复罐,是在線程創(chuàng)建的時創(chuàng)建,它的生命周期也是跟隨線程的生命周期雄家,線程結(jié)束棧內(nèi)存也就釋放效诅,對于棧來說不存在垃圾回收問題,只要線程一結(jié)束該棧就Over趟济,是線程私有的乱投。
8種數(shù)據(jù)類型的變量+對象的引用變量+實例方法都是在函數(shù)的棧內(nèi)存中分配。
棧主要存儲什么
本地變量: 輸入?yún)?shù)和輸出參數(shù)以及方法內(nèi)的變量
棧操作: 記錄出棧顷编、入棧的操作
棧幀數(shù)據(jù): 類文件戚炫、方法等等
虛擬機棧的棧元素是棧幀,當(dāng)有一個方法被調(diào)用時媳纬,代表這個方法的棧幀入棧双肤;當(dāng)這個方法返回時,其棧幀出棧
http://www.importnew.com/26842.html/vm_stack
http://www.importnew.com/26842.html
堆(heap)
一個JVM實例只存在一個堆內(nèi)存钮惠,堆內(nèi)存的大小是可以調(diào)節(jié)的茅糜。類加載器讀取了類文件后,需要把類素挽、方法蔑赘、常變量放到堆內(nèi)存中,保存所有引用類型的真實信息预明,以方便執(zhí)行器執(zhí)行.
引用一張圖