41.JVM方法區的內部結構(方法區中存儲的是什么)


 

1.方法區內部結構

Java代碼被編譯成字節碼文件之后,通過類加載器被加載到運行時數據區。其中,方法區主要存儲的是類型的相關信息以及運行時常量池。對於字符串常量,根據JDK版本的不同,有的放到了方法區,有的沒有。
在這里插入圖片描述
方法區中存放的是類型信息、常量、靜態變量、即時編譯器編譯后的代碼緩存、域信息、方法信息等。隨着JDK的發展,方法區中存放的內容也在發生變化。並不絕對。通常情況下放的是這些內容。
在這里插入圖片描述
1.類型信息
在這里插入圖片描述
2.域信息 ==> 成員變量信息
在這里插入圖片描述
3.方法信息
在這里插入圖片描述
例子:下面是一個Java程序的字節碼文件通過javap反編譯之后得到的輸出。
class文件中的類型信息、域信息、方法信息都會被類加載器加載到方法區中。

  Last modified 2020-4-22; size 1626 bytes
  MD5 checksum 69643a16925bb67a96f54050375c75d0
  Compiled from "MethodInnerStrucTest.java"
  //類型信息會被加載到方法區
public class com.atguigu.java.MethodInnerStrucTest extends java.lang.Object // 類的全限定名以及父類
implements java.lang.Comparable<java.lang.String>, java.io.Serializable //類實現的接口信息
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER // 類的權限修飾符
Constant pool:
   #1 = Methodref          #18.#52        // java/lang/Object."<init>":()V
   #2 = Fieldref           #17.#53        // com/atguigu/java/MethodInnerStrucTest.num:I
   #3 = Fieldref           #54.#55        // java/lang/System.out:Ljava/io/PrintStream;
   ...
{
  //域信息會被加載到方法區
  public int num; // 域名稱
    descriptor: I // 域類型
    flags: ACC_PUBLIC // 域權限

  private static java.lang.String str;
    descriptor: Ljava/lang/String;
    flags: ACC_PRIVATE, ACC_STATIC

  //方法信息會被加載到方法區
  public com.atguigu.java.MethodInnerStrucTest(); // 方法名稱
    descriptor: ()V //方法參數及方法返回值類型
    flags: ACC_PUBLIC //方法權限修飾符
    Code: //方法對應的字節碼
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: bipush        10
         7: putfield      #2                  // Field num:I
        10: return
      LineNumberTable:
        line 10: 0
        line 12: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  this   Lcom/atguigu/java/MethodInnerStrucTest;
            ......
}
Signature: #49                          // Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/String;>;Ljava/io/Serializable;
SourceFile: "MethodInnerStrucTest.java"

2.non-final的類變量與final的類變量初始化的時間

non-final的類變量:就是static的成員變量。
在這里插入圖片描述
final的類變量:就是static final的成員變量。
在這里插入圖片描述

初始化的區別:初始化的時間不同,non-final的類變量在類加載的第二個階段(鏈接階段)的准備階段被賦默認的初始值,然后再類加載的第三個階段(初始化階段)被顯示初始化(也就是賦值為代碼中寫的值)。
比如: 定義一個成員變量apublic static int a = 7; a在鏈接階段的准備階段被賦默認值0;然后再初始化階段被顯示初始化為7

final的類變量是在編譯階段就被顯示初始化了。
比如:定義一個成員變量, public static final int a = 7; ,a在代碼被編譯成字節碼文件的時候就被賦值為7了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM