日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JVM模型学习笔记

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JVM模型学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JVM由三個主要的子系統構成

1. 運行時數據區(內存結構):

運行時數據區也是JVM的核心部分

內存數據區又分:堆、java棧、本地方法棧、程序計數器、方法區

1.1 本地方法棧(線程私有):

登記native方法,在Execution Engine執行時加載本地方法庫


1.2 程序計數器(線程私有):

就是一個指針,指向方法區中的方法字節碼(用來存儲指向下一條指令的地址,也即將要執行的指令代碼),由執行引擎讀取下一條指令,是一個非常小的內存空間,幾乎可以忽略不記。

1.3 方法區(線程共享):

類的所有字段和方法字節碼,以及一些特殊方法如構造函數,接口代碼也在此定義。簡單說,所有定義的方法的信息都保存在該區域,靜態變量+常量+類信息(構造方法/接口定義)+運行時常量池都存在方法區中,雖然Java虛擬機規范把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做 Non-Heap(非堆),目的應該是與 Java 堆區分開來。

1.4 Java棧(線程私有):

Java線程執行方法的內存模型,一個線程對應一個棧,每個方法在執行的同時都會創建一個棧幀(用于存儲局部變量表,操作數棧,動態鏈接,方法出口等信息)不存在垃圾回收問題,只要線程一結束該棧就釋放,生命周期和線程一致

JVM對該區域規范了兩種異常:
1) 線程請求的棧深度大于虛擬機棧所允許的深度,將拋出StackOverFlowError異常
2) 若虛擬機棧可動態擴展,當無法申請到足夠內存空間時將拋出OutOfMemoryError,通過jvm參數–Xss指定棧空間,空間大小決定函數調用的深度

1.5 棧針:

每一個線程會有很多個棧針,每一個棧針代表該線程要執行的一個方法,以下是棧針內部的結構:

1.6堆(線程共享):

虛擬機啟動時創建,用于存放對象實例,幾乎所有的對象(包含常量池)都在堆上分配內存,當對象無法再該空間申請到內存時將拋出OutOfMemoryError異常。同時也是垃圾收集器管理的主要區域。可通過 -Xmx –Xms 參數來分別指定最大堆和最小堆

?上圖為堆的內存模型,堆可分為 新生代老年代元數據區(JDK1.8以后出現的)

新生代:
類誕生、成長、消亡的區域,一個類在這里產生,應用,最后被垃圾回收器收集,結束生命。
新生區分為兩部分: 伊甸區(Eden space)和幸存者區(Survivor pace) ,所有的類都是在伊甸區被new出來的。幸存區有兩個: 0區(Survivor 0 space)和1區(Survivor 1 space)。當伊甸園的空間用完時,程序又需要創建對象,JVM的垃圾回收器將對伊甸園區進行垃圾回收(Minor GC),將伊甸園區中的不再被其他對象所引用的對象進行銷毀。然后將伊甸園中的剩余對象移動到幸存 0區。若幸存 0區也滿了,再對該區進行垃圾回收,放到 1區,默認1和0兩區交替回收15次后,還存活的對象就進入老年代。

老年代:

新生代經過多次GC仍然存活的對象移動到老年區。若老年區也滿了,那么這個時候將產生MajorGC(FullGC),進行老年區的內存清理。若老年區執行了Full GC之后發現依然無法進行對象的保存,就會產生OOM異常“OutOfMemoryError”

元數據區:

元數據區取代了永久代(jdk1.8以前),本質和永久代類似,都是對JVM規范中方法區的實現,區別在于元數據區并不在虛擬機中,而是使用本地物理內存,永久代在虛擬機中,永久代邏輯結構上屬于堆,但是物理上不屬于堆,堆大小=新生代+老年代。元數據區也有可能發生OutOfMemory異常。
Jdk1.6及之前: 有永久代, 常量池在方法區
Jdk1.7:?????? 有永久代,但已經逐步“去永久代”,常量池在堆
Jdk1.8及之后: 無永久代,常量池在元空間

元數據區的動態擴展,默認–XX:MetaspaceSize值為21MB的高水位線。一旦觸及則Full GC將被觸發并卸載沒有用的類(類對應的類加載器不再存活),然后高水位線將會重置。新的高水位線的值取決于GC后釋放的元空間。如果釋放的空間少,這個高水位線則上升。如果釋放空間過多,則高水位線下降。
為什么jdk1.8用元數據區取代了永久代?
官方解釋:移除永久代是為融合HotSpot JVM與 JRockit VM而做出的努力,因為JRockit沒有永久代,不需要配置永久代

2.類加載器子系統:

2.2 類加載:

類加載器將class文件加載到虛擬機的內存
?? ???? 加載:在硬盤上查找并通過IO讀入字節碼文件
?? ??? ?連接:執行校驗、準備、解析(可選)步驟
?? ??? ?校驗:校驗字節碼文件的正確性
?? ??? ?準備:給類的靜態變量分配內存,并賦予默認值
?? ??? ?解析:類裝載器裝入類所引用的其他所有類
?? ??? ?初始化:對類的靜態變量初始化為指定的值,執行靜態代碼塊

2.3 類加載器種類:

啟動類加載器:負責加載JRE的核心類庫,如jre目標下的rt.jar,charsets.jar等
擴展類加載器:負責加載JRE擴展目錄ext中JAR類包,如JRE\lib\ext 下的.jar
系統類加載器:負責加載ClassPath路徑下的類包
用戶自定義加載器:負責加載用戶自定義路徑下的類包,如tomcat會自己寫類加載器

2.4 類加載機制

全盤負責委托機制:當一個ClassLoader加載一個類時,除非顯示的使用另一個ClassLoader,該類所依賴和引用的類也由這個ClassLoader載入
雙親委派機制:指先委托父類加載器尋找目標類,在找不到的情況下在自己的路徑中查找并載入目標類

雙親委派的意義:

沙箱安全機制:自己寫的String.class類不會被加載,這樣便可以防止核心API庫被隨意篡改
避免類的重復加載:當父親已經加載了該類時,就沒有必要子ClassLoader再?? 加載一次

?


3.執行引擎:

讀取運行時數據區的Java字節碼并逐個執行

總結

以上是生活随笔為你收集整理的JVM模型学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。