美文网首页
Jvm学习笔记(二)

Jvm学习笔记(二)

作者: windfall_ | 来源:发表于2016-11-12 22:50 被阅读0次

    Class类文件结构


    Class类文件结构
    • 无符号数:u1、u2、u4、u8分别代表1个字节、2个字节、4个字节、8个字节

    • magic:魔数,4个字节,唯一取值"0xCAFEBABE"

    • minjor_version、major_version:Class文件版本号

    • constant_pool_count:由于常量池数量不固定,在常量池入口放置一2字节类型数据,代表常量池容量计数。计数从1开始。即constant_pool_count = constant_pool长度+1 。

    • constant_pool:常量池。包括字面量和符号引用。字面量指java中的字符串和final类型常量等。符号引用包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。

    常量池标志位

    CONSTANT_Class_info结构里包含一个name_index,指向一个 CONSTANT_Utf8_info,为这个类的全限定名。CONSTANT_Utf8_info结构包含length,和bytes。

    CONSTANT_Class_info {
        u1 tag;   //tag取值为7,代表CONSTANT_Class_info
        u2 name_index;  //name_index表示代表自己类名的字符串信息位于于常量池数组中哪一个,也就是索引
    }
    
    CONSTANT_Utf8_info {
        u1 tag;
        u2 length;  //下面就是存储UTF8字符串的地方了
        u1 bytes[length];
    }
    
    CONSTANT_NameAndType_info {
       u1 tag;
       u2 name_index;  //方法名或域名对应的字符串索引
       u2 descriptor_index; //方法信息(参数+返回值),或者成员变量的信息(类型)对应的字符串索引
    }
    
    CONSTANT_Fieldref_info {
       u1 tag;
       u2 class_index;  
       u2 name_and_type_index; 
    }
    
    CONSTANT_Methodref_info {
       u1 tag;
       u2 class_index;  
       u2 name_and_type_index;
    }
    
    CONSTANT_InterfaceMethodref_info {
       u1 tag;
       u2 class_index;  
       u2 name_and_type_index; 
    }
    
    • access_flags:标志位。包括:这个 Class 是类还是接口,是否定义为 public 类型,abstract 类型,如果是类的话,是否声明为 final,等等。

    • this_class、super_class:类索引、父类索引。

    • interfaces、fields、methods:接口、变量、方法。

    • attributes:属性表。


    示例:

    public class TestMain{
        public int x = 0;
    
        public static void main (String [] args){
            TestMain testMain = new TestMain();
            testMain.test();
        }
    
        public TestMain(){
    
        }
        public void test(){
            
        }
    }
    

    javap -verbose

    public class TestMain                                                                 
      minor version: 0                                                                    
      major version: 52                                                                   
      flags: ACC_PUBLIC, ACC_SUPER                                                        
    Constant pool:                                                                        
       #1 = Class              #18            // TestMain                                 
       #2 = Methodref          #1.#19         // TestMain."<init>":()V                    
       #3 = Methodref          #1.#20         // TestMain.test:()V                        
       #4 = Methodref          #6.#19         // java/lang/Object."<init>":()V            
       #5 = Fieldref           #1.#21         // TestMain.x:I                             
       #6 = Class              #22            // java/lang/Object                         
       #7 = Utf8               x                                                          
       #8 = Utf8               I                                                          
       #9 = Utf8               main                                                       
      #10 = Utf8               ([Ljava/lang/String;)V                                     
      #11 = Utf8               Code                                                       
      #12 = Utf8               LineNumberTable                                            
      #13 = Utf8               <init>                                                     
      #14 = Utf8               ()V                                                        
      #15 = Utf8               test                                                       
      #16 = Utf8               SourceFile                                                 
      #17 = Utf8               TestMain.java                                              
      #18 = Utf8               TestMain                                                   
      #19 = NameAndType        #13:#14        // "<init>":()V                             
      #20 = NameAndType        #15:#14        // test:()V                                 
      #21 = NameAndType        #7:#8          // x:I                                      
      #22 = Utf8               java/lang/Object                                           
    {                                                                                     
      public int x;                                                                       
        descriptor: I                                                                     
        flags: ACC_PUBLIC                                                                 
                                                                                          
      public static void main(java.lang.String[]);                                        
        descriptor: ([Ljava/lang/String;)V                                                
        flags: ACC_PUBLIC, ACC_STATIC                                                     
        Code:                                                                             
          stack=2, locals=2, args_size=1                                                  
             0: new           #1                  // class TestMain                       
             3: dup                                                                       
             4: invokespecial #2                  // Method "<init>":()V                  
             7: astore_1                                                                  
             8: aload_1                                                                   
             9: invokevirtual #3                  // Method test:()V                      
            12: return                                                                    
          LineNumberTable:                                                                
            line 5: 0                                                                     
            line 6: 8                                                                     
            line 7: 12                                                                    
                                                                                          
      public TestMain();                                                                  
        descriptor: ()V                                                                   
        flags: ACC_PUBLIC                                                                 
        Code:                                                                             
          stack=2, locals=1, args_size=1                                                  
             0: aload_0                                                                   
             1: invokespecial #4                  // Method java/lang/Object."<init>":()V 
             4: aload_0                                                                   
             5: iconst_0                                                                  
             6: putfield      #5                  // Field x:I                            
             9: return                                                                    
          LineNumberTable:                                                                
            line 9: 0                                                                     
            line 2: 4                                                                     
            line 11: 9                                                                    
                                                                                          
      public void test();                                                                 
        descriptor: ()V                                                                   
        flags: ACC_PUBLIC                                                                 
        Code:                                                                             
          stack=0, locals=1, args_size=1                                                  
             0: return                                                                    
          LineNumberTable:                                                                
            line 14: 0                                                                    
    }                                                                                     
    SourceFile: "TestMain.java"                                                           
                                                                                          
    
    • 如上,在常量池中,第一个元素为Class,即CONSTANT_Class_info,它的name_index为第18个元素,即Utf8_info,内容为字符串"TestMain"。第二个元素为Methodref_info,其class_index为第一个元素,即"TestMain",name_and_type_index为第19个元素,对应第13个元素和第14个元素,V代表void。以此类推。

    • Code属性:

      • stack=2,locals=2,args_size=1。结合代码,main函数确实有一个参数,而且还有一个本地变量。注意,main函数是static的。如果对于类的非static函数,那么locals的第0个元素代表this。stack表示操作数最大栈深度。locals表示局部变量所需要的空间,以slot为单位。args_size参数个数。
      • stack后面接下来的就是code数组,也就是这个函数对应的执行代码。0表示code[]的索引位置。0:new:代表这个操作是new操作,此操作对应的字节码长度为3,所以下一个操作对应的字节码从索引3开始。
      • LineNumberTable:也是属性的一种,用于调试,它将源码和字节码匹配了起来。比如line 5: 0这句话代表该函数字节码0那一个操作对应代码的第5行。

    相关文章

      网友评论

          本文标题:Jvm学习笔记(二)

          本文链接:https://www.haomeiwen.com/subject/aknfpttx.html