Change Dir

          先知cd——熱愛生活是一切藝術(shù)的開始

          統(tǒng)計

          留言簿(18)

          積分與排名

          “牛”們的博客

          各個公司技術(shù)

          我的鏈接

          淘寶技術(shù)

          閱讀排行榜

          評論排行榜

          JVM學(xué)習(xí)筆記(1)——java class

          例子主要是《深入jvm》中的例子,class文件是其中的act.class,java源文件是:

          class Act {

              public static void doMathForever() {
                  int i = 0;
                  for (;;) {
                      i += 1;
                      i *= 2;
                  }
              }
          }

          class文件hex形式:

          CA FE BA BE 00 03 00 2D  00 11 07 00 07 07 00 10
          0A 00 02 00 04 0C 00 06  00 05 01 00 03 28 29 56
          01 00 06 3C 69 6E 69 74  3E 01 00 03 41 63 74 01
          00 08 41 63 74 2E 6A 61  76 61 01 00 04 43 6F 64
          65 01 00 0D 43 6F 6E 73  74 61 6E 74 56 61 6C 75
          65 01 00 0A 45 78 63 65  70 74 69 6F 6E 73 01 00
          0F 4C 69 6E 65 4E 75 6D  62 65 72 54 61 62 6C 65
          01 00 0E 4C 6F 63 61 6C  56 61 72 69 61 62 6C 65
          73 01 00 0A 53 6F 75 72  63 65 46 69 6C 65 01 00
          0D 64 6F 4D 61 74 68 46  6F 72 65 76 65 72 01 00
          10 6A 61 76 61 2F 6C 61  6E 67 2F 4F 62 6A 65 63
          74 00 20 00 01 00 02 00  00 00 00 00 02 00 09 00
          0F 00 05 00 01 00 09 00  00 00 30 00 02 00 01 00
          00 00 0C 03 3B 84 00 01  1A 05 68 3B A7 FF F9 00
          00 00 01 00 0C 00 00 00  12 00 04 00 00 00 05 00
          02 00 07 00 05 00 08 00  09 00 06 00 00 00 06 00
          05 00 01 00 09 00 00 00  1D 00 01 00 01 00 00 00
          05 2A B7 00 03 B1 00 00  00 01 00 0C 00 00 00 06
          00 01 00 00 00 02 00 01  00 0E 00 00 00 02 00 08

          1. java的class文件是8位二進制流,數(shù)據(jù)項按順序存放,無間隔,占多字節(jié)的數(shù)據(jù)項以高位在前的順序分幾個字節(jié)存放;
          2. java class基本類型:u1,u2,u4,u8,分別對應(yīng):1,2,4,8字節(jié)的無符號類型;
          3. java class file表格展示:(太大了,來個url自己看吧,wikipedia
          4. 表項詳解:1)magic(魔數(shù)):說白了就是cafebabe,本來java就是咖啡嘛,這4個字節(jié)用來區(qū)分是否是java的class文件,有則是;2)minor_version&major_version:兩個字節(jié)的minor和兩個字節(jié)的major,以上為例就是minor:3,major:2D(JDK 1.1);3)再之后就是常量池了,2個字節(jié)表示constant_pool_count,本例是17,表示class文件中常量池中的項數(shù)(比實際的大1),接著就是常量池,連續(xù)的constant_pool_count-1個字節(jié)存儲常量池各個入口,常量池入口項解釋見本文第5條筆記;4)在之后的是access_flags:2個字節(jié)表示訪問類型,是類還是接口,是public還是private,abstract或者final等等,標(biāo)志位具體定義見本文第6條筆記,本例是00 20,表示老版本ACC_SUPER;5)之后是this_class,這是2字節(jié)的一個對常量池的索引,本例是00 01,即本例的自身類叫做Act;6)之后就是super_class,也是一個2字節(jié)常量池索引,指向父類的名字, 本例是00 02,即java.lang.Object;7)interface_count和interfaces:interface_count指出本文件有多少直接實現(xiàn)或者由接口擴展的父接口的數(shù)量,本例沒有,故為00 00,之后是interfaces的具體內(nèi)容,實際的項數(shù)就是之前的interface_count數(shù),因為interface_count=0,所以本例的interfaces就沒有值;8)接下來是fields_count和fields:對本類所聲明的字段的描述,首先是個2字節(jié)的count,本例是00 00,所以后續(xù)也沒有fields的項;9)再之后就是methods_count和methods了,count是一個2字節(jié)數(shù)據(jù),本例的method_count是00 02,這個count只表示在類或接口中顯式定義的方法,繼承的方法不計數(shù),count后是method_info的表,包含方法的一些信息如方法名、描述符等,本例中00 09表明方法是public(01)&static(08),00 0F是方法名的常量池入口,即常量池的第15項doMathForever,再下來00 05是方法描述符常量池入口,即常量池第5項:()V,然后00 01是屬性表的count數(shù),表示1項屬性,接下來是00 09表示屬性表的常量池入口即常量池第9項Code,接下來的4個字節(jié)00 00 00 30表示code屬性長度:48字節(jié),接著00 02是操作數(shù)最大數(shù),然后00 01是局部變量存儲長度,這里方法里只有一個變量i,所以是1,然后00 00 00 0c是code字節(jié)碼長度12,然后的12個字節(jié)就是字節(jié)碼code了,再后的00 00是異常數(shù),之后異常棧數(shù)是0,跳過,就是00 01的屬性數(shù),然后00 0C指向常量池的第12項即LineNumberTable,這是一個code屬性,之后的00 00 00 12是屬性長度,再后的00 04是line_number_info表的項數(shù),接下來的4項(每項4字節(jié))表示line_number_info,00 00 表示代碼偏移量,00 05表示代碼行號,后面的類似;10)最后是attributes_count和attributes,表明了類的屬性,屬性比較特殊,jvm定義了兩種屬性:SourceCode和InnerClass。
          5. 常量池各個標(biāo)志解讀(來源wikipedia)image ,這里詳解一下本例中的常量池,常量池是
            cp_info
                   {
                       tag;
                       info[];
                   }
            類似這樣的結(jié)構(gòu),先有一個無符號byte作為tag標(biāo)志,對應(yīng)表格中的數(shù)據(jù),額外的info字節(jié)數(shù)組存儲對應(yīng)的數(shù)據(jù)index.
            我以表格的形式列出常量池的所有數(shù)據(jù),應(yīng)該算一目了然了吧:
          6. 常量index 標(biāo)志 標(biāo)志內(nèi)容 字節(jié) 具體數(shù)據(jù) 實際含義
            1 07 00 07 2 class reference 常量池第7項是該class的內(nèi)容
            2 07 00 10 2 class reference 常量池第16項是該class的內(nèi)容
            3 0A 00 02 00 04 4 method ref 兩個index,前兩個字節(jié)表示池內(nèi)的class索引位置,后兩個字節(jié)是名字和類型描述
            4 0C 00 06 00 05 4 name & type 就是第3項方法指向的名字和類型的index
            5 01 00 03 2+x x個utf-8字符,此處x=3 實際值:()V,表示type(第三項方法的類型,具體含義參見描述符定義)
            6 01 00 06 2+x x=6 實際值:<init>,表示name(第三項方法的名字)
            7 01 00 03 2+x x=3 實際值:Act,第一項指向的具體字符內(nèi)容
            8 01 00 08 2+x x=8 實際值:Act.java,
            9 01 00 04 2+x x=4 實際值:Code
            10 01 00 0D 2+x x=0D=13 實際值:ConstantValue
            11 01 00 0A 2+x x=0A=10 實際值:Exceptions
            12 01 00 0F 2+x x=0F=15 實際值:LineNumberTable
            13 01 00 0E 2+x x=0E=14 實際值:LocalVariable
            14 01 00 0A 2+x x=0A=10 實際值:SourceFile
            15 01 00 0D 2+x x=0D=13 實際值:doMathForever
            16 01 00 10 2+x x=10=16 實際值:java/lang/Object
          7. 訪問標(biāo)志,待完善,這里有詳細的spec
          8. 描述符的完整定義:非終結(jié)符是正常體,終結(jié)符是粗體,*號表示之前符號出現(xiàn)0或多次
            FieldDescriptor FieldType
            ComponentType FieldType
            FieldType BaseType,ObjectType,ArrayType
            BaseType B,C,D,F,I,J,S,Z
            ObjectType L<classname>;
            ArrayType [ComponentType
            MethodDescriptor (ParameterDescriptor*)ReturnDescriptor
            ParameterDescriptor FieldType
            ReturnDescriptor FieldType,V
          9. 基本類型終結(jié)符:V代表void
            終結(jié)符 類型
            B byte
            C char
            D double
            F float
            I int
            J long
            S short
            Z boolean
          10. 一些描述符的例子:
            描述符 字段或方法聲明
            I int a;
            [[J long[][] b;
            [Ljava/lang/Object; java.lang.Object[] c;
            Ljava/util/HashMap; java.util.HashMap map;
            [[[Z boolean[][][] ok;
            ()I int m1();
            ()Ljava/lang/String; String m2();
            ([Ljava/lang/String;)V void main(String[] args);
            ()V void m3();
            (JI)V void m4(long a,int b);
            (Z[Ljava/lang/String;II)Z boolean m5(boolean a,String[] b,int c, int d);
            ([BII)I int m6(byte[] a,int b,int c);
          11. 聲明字段時的字段表field_info:
            類型 名稱 數(shù)量 含義
            u2 access_flags 1 訪問標(biāo)志
            u2 name_index 1 字段簡單名稱的常量池utf8_info入口索引
            u2 descriptor_index 1 字段描述符的常量池utf8_info入口索引
            u2 attributes_count 1 attribute_info表的項數(shù)
            attribute_info attributes attributes_count 字段屬性:ConstantValue, Deprecated, Synthetic(JVM規(guī)范)
          12. field_info中的access_flags標(biāo)志含義:
            標(biāo)志名 含義 使用范圍
            ACC_PUBLIC 0x0001 public 類和接口
            ACC_PRIVATE 0x0002 private
            ACC_PROTECTED 0x0004 protected
            ACC_STATIC 0x0008 static 類和接口
            ACC_FINAL 0x0010 final 類和接口
            ACC_VOLATILE 0x0040 volatile
            ACC_TRANSIENT 0x0080 transient
          13. 聲明方法時的方法表method_info:
            類型 名稱 數(shù)量 含義
            u2 access_flags 1 訪問修飾符
            u2 name_index 1 方法簡單名稱的常量池入口
            u2 descriptor_index 1 方法描述符的常量池入口
            u2 attributes_count 1 屬性表的項數(shù)
            attribute_info attributes attributes_count 方法屬性:Code,Deprecated, Exceptions和Synthetic(JVM規(guī)范)
          14. method_info表中的訪問標(biāo)志對應(yīng)含義:值得說明的是接口的方法一定是public和abstract的,接口初始化方法可以用strictFP
            標(biāo)志名 含義 使用范圍
            ACC_PUBLIC 0x0001 public 類和接口
            ACC_PRIVATE 0x0002 private
            ACC_PROTECTED 0x0004 protected
            ACC_STATIC 0x0008 static
            ACC_FINAL 0x0010 final
            ACC_SYNCHRONIZED 0x0020 synchronized
            ACC_NATIVE 0x0100 native
            ACC_ABSTRACT 0x0400 abstract 類和接口
            ACC_STRICT 0x0800 strictFP 類和接口的<clinit>方法
          15. 類和接口的初始化方法(<clinit>)只有JVM可以直接調(diào)用,永遠不會被java字節(jié)碼直接調(diào)用。
          16. JVM規(guī)范定義的所有屬性:
            屬性名 使用者 描述
            Code method_info 方法的字節(jié)碼和其他數(shù)據(jù)
            ConstantValue field_info final變量的值
            Deprecated field_info,method_info 字段或方法被禁用的指示符
            Exceptions method_info 方法可能拋出的可被檢測的異常
            InnerClasses ClassFile 內(nèi)部、外部類的列表
            LineNumberTable Code_attribute 方法的行號與字節(jié)碼的映射
            LocalVariableTable Code_attribute 方法的局部變量的描述
            SourceFile ClassFile 源文件名
            Synthetic field_info,method_info 編譯器產(chǎn)生的字段或者方法的指示符
          17. code屬性的表code_attribute:
            類型 名稱 數(shù)量 含義
            u2 attribute_name_index 1 包含“Code”的常量池入口
            u4 attribute_length 1 去除起始6個字節(jié)后的code屬性長度
            u2 max_stack 1 方法執(zhí)行任意時刻,該方法操作數(shù)棧的最大長度(以字為單位)
            u2 max_locals 1 方法局部變量需要的存儲空間長度(以字為單位)
            u4 code_length 1 該方法字節(jié)碼流的長度
            u1 code code_length  
            u2 exception_table_length 1 異常表項數(shù)
            exception_info exception_table exception_table_length 異常表
            u2 attributes_count 1 屬性數(shù)
            attribute_info attributes attributes_count code屬性:LineNumberTable和LocalVariableTable(JVM規(guī)范)
          18. 異常表excption_info:
            類型 名稱 數(shù)量 含義
            u2 start_pc 1 代碼數(shù)組起始處到異常處理器起始處的代碼偏移量
            u2 end_pc 1 代碼數(shù)組起始處到異常處理器結(jié)束后的一個字節(jié)的偏移量
            u2 handler_pc 1 代碼數(shù)組起始處跳轉(zhuǎn)到異常處理器的第一條指令的偏移量
            u2 catch_type 1 異常處理器捕獲的異常類型的Class_info常量池入口,如果為0則表示處理finally子句,即處理所有異常
          19. constantValue屬性:各種基礎(chǔ)類型加字符串類型的常量池入口查找,結(jié)構(gòu)很簡單,這里就不列出了。
          20. LineNumberTable屬性建立了方法字節(jié)碼流便宜量和源代碼行號之間的映射關(guān)系:
            類型 名稱 數(shù)量 含義
            u2 attribute_name_index 1 包含“LineNumberTable”的常量池入口
            u4 attribute_length 1 去除起始6字節(jié)后的屬性長度
            u2 line_number_table_length 1 line_number_info表長度
            line_number_info line_number_table line_number_
            table_length
            屬性表
          21. line_number_info表很簡單,就兩個項:u2的start_pc給出新行開始時代碼數(shù)組的偏移量,u2的line_number給出了從start_pc開始的行號。

           

          這次就到這里。to be continued...

          posted on 2012-09-17 16:38 changedi 閱讀(522) 評論(0)  編輯  收藏 所屬分類: Java技術(shù)

          主站蜘蛛池模板: 宁化县| 珲春市| 治多县| 平潭县| 稷山县| 孟州市| 额尔古纳市| 西林县| 盐源县| 青海省| 甘孜| 布尔津县| 手机| 高邑县| 称多县| SHOW| 红原县| 三门峡市| 侯马市| 巴青县| 天门市| 连云港市| 环江| 中牟县| 商洛市| 金溪县| 康马县| 方山县| 胶南市| 封开县| 西乡县| 高邑县| 玉环县| 明光市| 栾川县| 泰和县| 广宁县| 临沭县| 钟山县| 襄樊市| 永修县|