方法區(Method Area)
① 對每個加載的類型,JVM必須在方法區中存儲以下類信息:
1) 這個類型的完整有效名(類型信息)
類型名稱在Java類文件和JVM中都以完整有效名出現。在java源代碼中,完整有效名由類的所屬包名稱加一個".",再加上類名組成。例如,類Object的所屬包為java.lang,那它的完整有效名為java.lang.Object,但在類文件里,所有的"."都被斜杠“/”代替,就成為java/lang/Object。完整有效名在方法區中的表示根據不同的實現而不同。
2) 這個類型直接父類的完整有效名(除非這個類型是interface或是 java.lang.Object,兩種情況下都沒有父類
3) 這個類型的修飾符(Public,Abstract, Final的某個子集)
4) 這個類型直接接口的一個有序列表
② 除了以上的基本信息外,JVM還要為每個類型保存以下信息:
1) 類型的常量池(Constant Pool)
JVM為每個已加載的類型都維護一個常量池。
常量池就是這個類型用到的常量的一個有序集合,包括實際的常量/字面量(String,Integer和Floating Point浮點常量)和對類型,域和方法的符號引用。池中的數據項象數組項一樣,是通過索引訪問的。 因為常量池存儲了一個類型所使用到的所有類型,域和方法的符號引用
字面量:是用於表達源代碼中一個固定值的表示法(如文本字符串,聲明為final的常量值等)
常量: (被聲明為final的類變量)每個常量都會在常量池中有一個拷貝。non-final類變量被存儲在聲明它的類信息內,而final類被存儲在所有使用它的類信息內。
符號引用:(符號引用以一組符號來描述所引用的目標,符號可以是任何形式的字面量,只要使用時能夠無歧義的定位到目標即可—保證唯一性)類和接口的全限定名、 字段的名稱和描述符、方法的名稱和描述符。符號引用與虛擬機的內存布局無關,引用的目標並不一定加載到內存中。在Java中,一個java類將會編譯成一個class文件。在編譯時,java類並不知道所引用的類的實際地址,因此只能使用符號引用來代替。(類似於CONSTANT_Class_info的常量來表示的)
常量池在Java程序的動態鏈接(運行期間也可能將新的常量放入池中)中起了核心的作用。
2) 域(Field)信息 (字段信息)
JVM必須在方法區中保存類型的所有域的相關信息以及域的聲明順序, 域的相關信息包括: 域名 、域類型 、域修飾符(public,private, protected,static,final,volatile,transient的某個子集)
域:域是一種屬性,可以是一個類變量(類的靜態變量),一個對象變量,一個對象方法變量或者是一個函數的參數
3) 方法信息
JVM必須保存所有方法的一下信息,同域信息一樣包含聲明順序,方法名、方法返回的類型(也可以是void)、方法參數的數量和類型(有序的)、方法的修飾符(public, private, protected, static, final, synchronized, native, abstract的一個子集)除了abstract和native方法外,其他方法還有保存方法的字節碼(bytecodes)、操作數棧和方法棧幀的局部變量區的大小、異常表
4) 類變量(除了常量外的所有靜態(static)變量)
類變量(類的靜態變量)被類的所有實例共享,即使沒有類實例時你也可以訪問它。這些變量只與類相關,所以在方法區中,它們成為類數據在邏輯上的一部分。在jvm使用一個類之前,它必須在方法區中為每個non-final類變量分配空間。
5) 指向類加載器的引用
每一個被JVM加載的類型,都保存這個類加載器的引用,類加載器動態鏈接時會用到。