JVM記憶體分配
先了解下JVM中的記憶體分配,此處以hotspot vm為例(官方jdk采用的vm)
程式計數器
堆疊
1. 虛擬機堆疊
2. 本地方法堆疊
Java堆
堆記憶體是各個執行緒共享的區域
方法區
它用于存盤已經被虛擬機加載的類資訊、常量、靜態變數、即編譯器編譯后的代碼等資料,靜態變數、常量在方法區,所有方法,包括靜態和非靜態的,也在方法區
這里解釋一下方法區:
首先方法區不是在堆中,在java8之前是用永久代實作的,永久代是 Hotspot 虛擬機特有的概念,雖然 Java 虛擬機規范把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做 Non-Heap(非堆),目的應該是與 Java 堆區分開來
java8之后是用元空間實作的,元空間并不在虛擬機中,而是使用本地記憶體,
只是 JVM 規范中定義的一個概念,用于存盤被 JVM 加載的類資訊、常量、靜態變數、即時編譯器編譯后的代碼等資料
常量池
常量池分為靜態常量池和運行時常量池
1. 靜態常量池
也叫 class檔案常量池,主要存放編譯期生成的各種字面量(Literal)和符號參考(Symbolic References),
final型別的常量在編譯期間就會進行分配,
靜態常量池指的是在編譯期確定,保存在class檔案中的一些資料,
靜態常量池是在編譯期間生成的,存盤在.class檔案中,
字面量(Literal)和符號參考量,字面量相當于Java語言層面常量的概念,如文本字串、宣告為final的常量值等,符號參考則屬于編譯原理方面的概念,包括了如下三種型別的常量:
-
1、類和介面的全限定名;
-
2、欄位的名稱和描述符;
-
3、方法的名稱和描述符,
2. 運行時常量池
當類加載到記憶體中后,JVM就會將class常量池中的內容存放到運行時常量池中;運行時常量池里面存盤的主要是編譯期間生成的字面量、符號參考等等,
類加載在鏈接環節的決議程序,會符號參考轉換成直接參考(靜態鏈接),此處得到的直接參考也是放到運行時常量池中的,
運行期間可以動態放入新的常量
運行時常量池記憶體位置:java8之前都在方法區中,java8之后在元空間
2.1 字串常量池
字串常量池,也可以理解成運行時常量池分出來的一部分,類加載到記憶體的時候,字串會存到字串常量池里面,利用池的概念,避免大量頻繁創建字串
-
JDK6時字串常量池位于運行時常量池,JDK7挪到堆中,
Hotspot8之前,使用持久代實作方法區,由于持久代記憶體不好估算,很容易到值OOM:Perm Gen例外,而元空間是本地記憶體,取決于作業系統分配記憶體,
字串常量池位置變遷
Jdk1.6及之前: 有永久代, 運行時常量池在永久代,運行時常量池包含字串常量池
Jdk1.7:有永久代,但已經逐步“去永久代”,字串常量池從永久代里的運行時常量池分離到堆里
Jdk1.8及之后: 無永久代,運行時常量池在元空間,字串常量池里依然在堆里
參考文章
(62條訊息) 深入理解java虛擬機(全章節完整)_TJtulong的博客-CSDN博客
(62條訊息) Java | JVM | 詳細圖解,堅持看完,帶你真正搞懂Java虛擬機_唐 城的博客-CSDN博客
(62條訊息) Java-雙親委派機制_七樓、的博客-CSDN博客
(62條訊息) Java-類加載器11127222七樓、的博客-CSDN博客
(62條訊息) jvm中的常量池到底在哪里?常量池在哪里yuan_qh的博客-CSDN博客
(62條訊息) Java方法區和永久代java永久代和方法區yuan_qh的博客-CSDN博客
這一次,徹底弄懂java中的常量池 - 掘金 (juejin.cn)
(62條訊息) JAVA常量池,一篇文章就足夠入門了,(含圖解)lei'chang'liang'chi河海哥yyds的博客-CSDN博客
(62條訊息) Java 常量池詳解(一)字串常量池_new hilbert()的博客-CSDN博客
徹底搞清楚class常量池、運行時常量池、字串常量池 - Awecoder - 博客園 (cnblogs.com)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/550099.html
標籤:其他
