8.方法區(執行緒共享)
阿新 • • 發佈:2021-07-08
一、棧、堆、方法區的互動關係
二、方法區的理解
jdk7是永久代的一個實現,jdk8是元空間的一個實現
和堆空間很類似,也是儲存資料的地方,載入的類太多的話,容易報OOM:metaSpace
三、設定方法區的大小與OOM
調優
四、方法區的內部結構
方法區主要存什麼?
型別資訊、常量資訊、靜態變數、即時編譯器編譯後的程式碼快取、類的載入器等
型別資訊:
對於每個的型別(類、介面、列舉、註解),JVM必須在方法區儲存一下資訊:
類(Class)資訊:
1>這個類的完整有效名稱
2>這個類的直接父類的完整有效名
3>這個類的修飾符
4>這個類的直接介面的一個有序列表
域(Filed)資訊:
名稱、型別、修飾符
方法(Method)資訊:
名稱、返回值型別、引數、修飾符、異常表
常量池表(Constant Pool Table)
包括各種字面量和對型別、域、方法的符號引用(地址)。
為什麼需要常量池呢?
比如說,有一個方法, 多個物件呼叫此方法,沒有必要宣告很多方法,、
只需要在常量池中宣告一個 此方法,然後多個物件呼叫它的話,直接指向它就好了;
(#XX 就是符號引用,指向真正的引用)
常量池中有什麼?
小結:
常量池,可以看做一張表,虛擬機器指令根據這張表找到要執行的類名、方法名、引數名、字面量等型別
執行時常量池
符號引用和真實引用 : 就好比 我的名字 和 我本人 我的名字就是符號引用 我的真人就是真實引用 執行時常量池方法區的一部分 常量池表是位元組碼檔案中的一部分,用於存放編譯期生成的各種字面量與符號引用,這部分內容在類載入後存放在方法區的 執行時常量池 中 此時,不再是常量池中的符號地址了,這裡轉為 真實地址 相對於常量池的一個重要特徵:動態性
五、方法區的舉例使用
第一步
第二步
先看程式計數器執行到哪了,然後壓入 運算元棧
第三步
然後執行下一步壓入本地變量表
...
第N步
下一步
六、方法區的演變細節
JDK6.......方法區(永久代)在JVM中
JDK7.......方法區(永久代)在JVM中
JDK8.......方法區(元空間)不在在JVM中,在本地記憶體
永久代為什麼要被元空間替代?
**1>永久代設定空間的大小 很難確定(空間小還容易產生full GC,大了還浪費)
如果動態載入類過多,容易產生OOM
元空間使用本地記憶體:元空間不在虛擬機器中,因此,元空間的大小僅售本地記憶體的影響
2>對永久代的調優很困難。(full GC)
**