JVM內存結構

java內存模型圖:


jvm內存模型粗略得可以分爲三個部分:堆內存,方法區,堆棧(線程私有)。
有些地方會把方法區歸爲堆內存,但實際上方法區還有另一個名字叫(非堆),也會被稱爲永久代(但實際上也會存在GC),不過java8已經把方法區移到了元空間,存在於本地內存。
堆內存可以分爲新生代區和老生代區,而新生代區有Eden,From Survivor,To Survivor(8:1:1)。

參數配置圖解:
在這裏插入圖片描述
-Xms 最小堆內存
-Xmx 最大堆內存
-XX:NewSize 最小新生代內存
-XX:MaxNewSize 最大新生代
-XX:PerSize 最先永久代內存
-XX:MaxPerSize 最大永久代呢村
-Xss: 單個線程棧內存大小

JVM與系統之間得關係圖:
在這裏插入圖片描述

類加載機制

  • 類加載過程:當java文件被編譯後,生成的.class文件會被類加載器加載到運行時數據區,然後執行鏈接的步驟,包含對字節碼內容進行驗證,初始化分配做準備(設置默認值),當該類被實例化時,則先執行初始化。
  • 最終結果:java文件被編譯成.class文件,類加載器把字節碼文件加載到運行時數據區,並在堆中創建類的相關java.lang.Class對象,用來封裝類在方法區的數據結構。jvm根據根據在這些數據運行程序。
  • 類加載器:java的類加載器概括來說包含兩種,啓動加載器和其他加載器;啓動加載器是虛擬機的一部分由c語言實現,他可以負責加載其他加載器的class。
  • 雙親委派模型:類加載器存在繼承關係時,當前類加載器會講需要加載的目標傳遞給父類加載器,當父類不能加載時,則就近加載;確保內存中只存在一份字節碼數據!

堆內存

作用:存儲程序中所有對象實例數據和類的Class對象(如上所說)的區域,爲所有線程之間共享。
結構:堆內存會被分有新生代和老生代,老生代又可以分爲伊甸區,FromSpace, ToSpace,其中不同區域對應的垃圾回收算法也會不同。

jvm中的垃圾回收算法:
標記清除-對於可回收的對象先標記再清除,效率高;適用於新生代對象更新頻繁,從而會留下更多大塊的內存區域。
標記整理-先標記,清除再整理,相比標記清楚,多了整理的步驟,所以適用於老生代不會頻繁調用回收機制。
複製算法:將內存分爲兩塊區域,輪流替換使用。不適合對象存活週期長的區域,頻繁的複製會大大降低迴收效率
分代回收算法:根據內存特徵選擇不同的回收算法

方法區

用途:保存的是被虛擬機加載的類信息,常量,靜態變量等編譯後的代碼信息。也是線程共享區域。
方法區的特點是對象的回收率低,存活週期長。因此,不適合使用複製算法回收
jdk1.8使用元空間代替方法區,元空間也不存在在虛擬內存中,而是使用的實際物理內存。

程序計數器

用途:記錄每個線程執行指令位置,爲線程私有。
程序計數器在內存中只會佔用一小塊內存,用於線程專門記錄指令執行位置,當CPU在線程之間進行切換的時候,便於線程恢復到相應的位置。

棧內存

用途:棧內存是線程私有,每開啓一個新線程都會創建一塊該線程所私有的內存。
a棧內存模擬了線程開始執行方法到結束的過程模型,
b線程沒執行一個方法都會創建一個棧幀,棧幀保存了方法中的局部變量,方法出口等信息。
棧幀所分配的內存在編譯期間就確定了。
異常:
1,當線程請求的站深度超過了jvm所規定的深度,則會拋出棧溢出異常。意思是線程調用方法深度超過了虛擬機規定的深度。
2,當線程無法申請到擴充棧的內存失敗時,會拋出內存溢出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章