亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java虛擬機(jī)原理:Class字節(jié)碼二進(jìn)制文件分析

 更新時(shí)間:2021年09月09日 09:12:47   作者:韓曙亮  
class文件全名稱為Java class文件,主要在平臺(tái)無(wú)關(guān)性和網(wǎng)絡(luò)移動(dòng)性方面使Java更適合網(wǎng)絡(luò)。它在平臺(tái)無(wú)關(guān)性方面的任務(wù)是:為Java程序提供獨(dú)立于底層主機(jī)平臺(tái)的二進(jìn)制形式的服務(wù)。下面我們來(lái)詳細(xì)解讀下它吧

一、字節(jié)碼文件 與 JVM

Java 源碼編譯成 Class 字節(jié)碼 ;

Java 虛擬機(jī) 可以被認(rèn)為是一個(gè) 解釋器 , 解釋編譯后的 Class 字節(jié)碼文件 , 最后在不同的操作系統(tǒng)中運(yùn)行 ;

Android 虛擬機(jī) 不是 Java 規(guī)范的 虛擬機(jī) , 有一些根據(jù)嵌入式設(shè)備進(jìn)行的定制的實(shí)現(xiàn) ;

Class 字節(jié)碼 本質(zhì)上就是 二進(jìn)制數(shù)據(jù) , 運(yùn)行時(shí) , 會(huì)被 類加載器 加載到 Java 虛擬機(jī)內(nèi)存的 方法區(qū) 中 ; 同時(shí) 創(chuàng)建 Class 對(duì)象 ;

( Java 虛擬機(jī)內(nèi)存分為 : 堆區(qū) , 方法區(qū) , 棧 , 本地方法棧 , 程序計(jì)數(shù)器 )

由于要將 Class 字節(jié)碼文件 加載到 JVM 內(nèi)存的 方法區(qū) 中 , 要占用一定的內(nèi)存空間 , 這里要求 Class 字節(jié)碼文件 , 越小越好 ;

二、字節(jié)碼文件示例

Java 源代碼如下 :

public class Student {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

使用 javac 命令將 Student.java 源碼編譯成 Student.class字節(jié)碼文件 :

javac Student.java

字節(jié)碼文件二進(jìn)制數(shù)據(jù)分析 :

使用二進(jìn)制查看工具查看 Student.class 字節(jié)碼文件 , 這些二進(jìn)制數(shù)值對(duì)應(yīng)的就是 JVM 指令 ;

在這里插入圖片描述

CA FE BA BE 00 00 00 34 00 15 0A 00 04 00 11 09
00 03 00 12 07 00 13 07 00 14 01 00 04 6E 61 6D
65 01 00 12 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53
74 72 69 6E 67 3B 01 00 06 3C 69 6E 69 74 3E 01
00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C
69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00
07 67 65 74 4E 61 6D 65 01 00 14 28 29 4C 6A 61
76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01
00 07 73 65 74 4E 61 6D 65 01 00 15 28 4C 6A 61
76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29
56 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00
0C 53 74 75 64 65 6E 74 2E 6A 61 76 61 0C 00 07
00 08 0C 00 05 00 06 01 00 07 53 74 75 64 65 6E
74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62
6A 65 63 74 00 21 00 03 00 04 00 00 00 01 00 02
00 05 00 06 00 00 00 03 00 01 00 07 00 08 00 01
00 09 00 00 00 1D 00 01 00 01 00 00 00 05 2A B7
00 01 B1 00 00 00 01 00 0A 00 00 00 06 00 01 00
00 00 01 00 01 00 0B 00 0C 00 01 00 09 00 00 00
1D 00 01 00 01 00 00 00 05 2A B4 00 02 B0 00 00
00 01 00 0A 00 00 00 06 00 01 00 00 00 05 00 01
00 0D 00 0E 00 01 00 09 00 00 00 22 00 02 00 02
00 00 00 06 2A 2B B5 00 02 B1 00 00 00 01 00 0A
00 00 00 0A 00 02 00 00 00 09 00 05 00 0A 00 01
00 0F 00 00 00 02 00 10

使用

javap -v Student.class

命令 , 生成上述字節(jié)碼文件的 附加信息 ;

命令行輸出 :

D:\jvm>javap -v Student.class
Classfile /D:/jvm/Student.class
  Last modified 2021-9-4; size 392 bytes
  MD5 checksum 8b9bb897bb8cf2a8addf04be5b7b915f
  Compiled from "Student.java"
public class Student
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#17         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#18         // Student.name:Ljava/lang/String;
   #3 = Class              #19            // Student
   #4 = Class              #20            // java/lang/Object
   #5 = Utf8               name
   #6 = Utf8               Ljava/lang/String;
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               getName
  #12 = Utf8               ()Ljava/lang/String;
  #13 = Utf8               setName
  #14 = Utf8               (Ljava/lang/String;)V
  #15 = Utf8               SourceFile
  #16 = Utf8               Student.java
  #17 = NameAndType        #7:#8          // "<init>":()V
  #18 = NameAndType        #5:#6          // name:Ljava/lang/String;
  #19 = Utf8               Student
  #20 = Utf8               java/lang/Object
{
  public Student();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0
  public java.lang.String getName();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #2                  // Field name:Ljava/lang/String;
         4: areturn
      LineNumberTable:
        line 5: 0
  public void setName(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #2                  // Field name:Ljava/lang/String;
         5: return
      LineNumberTable:
        line 9: 0
        line 10: 5
}
SourceFile: "Student.java"

在這里插入圖片描述

下面開(kāi)始逐個(gè)字節(jié)解析上述字節(jié)碼文件 ;

三、字節(jié)碼文件二進(jìn)制結(jié)構(gòu)分析

分析字節(jié)碼二進(jìn)制文件時(shí) , 可以參考 javap -v Student.class 命令輸出的字節(jié)碼附加信息進(jìn)行理解 ;

1、魔數(shù)

magic ( 魔數(shù) ) : 4 4 4 字節(jié) , CA FE BA BE , 所有的 Class 字節(jié)碼都是以 CafeBabe 信息開(kāi)頭的 ;

在這里插入圖片描述

2、次版本號(hào)

minor_version ( 次版本號(hào) ) : 2 2 2 字節(jié) , 00 00 , 次版本號(hào)是 0 0 0 ; 對(duì)應(yīng)字節(jié)碼附加信息中的 minor version: 0 ;

在這里插入圖片描述

3、主版本號(hào)

major_version ( 主版本號(hào) ) : 2 2 2 字節(jié) , 00 34 , 主版本號(hào)是 52 52 52 ; 對(duì)應(yīng)字節(jié)碼附加信息中的 major version: 52 ;

  • 這個(gè)主版本號(hào) 52 對(duì)應(yīng) JDK 版本的 1.8 版本 ;
  • 51 對(duì)應(yīng) 1.7 ;
  • 53 對(duì)應(yīng) 1.9 ;
  • 45 對(duì)應(yīng) 1.0 ;

在這里插入圖片描述

4、常量池個(gè)數(shù)

constant_pool_count ( 常量池個(gè)數(shù) ) : 2 2 2 字節(jié) , 00 15 , 常量池個(gè)數(shù)是 21 21 21 個(gè) ; 由于 JVM 占用了默認(rèn)的常量池 #0 , 因此實(shí)際上的常量個(gè)數(shù)是 21 − 1 21 - 1 21−1 個(gè) , 需要對(duì)這個(gè)數(shù)減一處理 ;

在這里插入圖片描述

字節(jié)碼附加信息中 常量池參考 , 有 20 20 20 個(gè)常量池 ; #0 常量池 , 被 JVM 占用了 , 代表了一個(gè)空引用 , 不指向任何位置 ;

Constant pool:
   #1 = Methodref          #4.#17         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#18         // Student.name:Ljava/lang/String;
   #3 = Class              #19            // Student
   #4 = Class              #20            // java/lang/Object
   #5 = Utf8               name
   #6 = Utf8               Ljava/lang/String;
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               getName
  #12 = Utf8               ()Ljava/lang/String;
  #13 = Utf8               setName
  #14 = Utf8               (Ljava/lang/String;)V
  #15 = Utf8               SourceFile
  #16 = Utf8               Student.java
  #17 = NameAndType        #7:#8          // "<init>":()V
  #18 = NameAndType        #5:#6          // name:Ljava/lang/String;
  #19 = Utf8               Student
  #20 = Utf8               java/lang/Object

總結(jié)

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

最新評(píng)論