1. 程式人生 > 其它 >8.方法區(執行緒共享)

8.方法區(執行緒共享)

一、棧、堆、方法區的互動關係

二、方法區的理解

	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)


**

StringTable為什麼要調整

七、方法區的垃圾收集

方法區的垃圾回收兩部分內容:常量池中廢棄的常量、不再使用的型別

變數的垃圾回收

類的垃圾回收

八、總結

九、大廠面試題