jvm探祕五:Class類檔案結構之屬性表
概述
在Class檔案、欄位表和方法表都可以攜帶自己的屬性資訊,這個資訊用屬性表進行描述,用於描述某些場景專有的資訊。
與Class檔案中其它資料項對長度、順序、格式的嚴格要求不同,屬性表集合不要求其中包含的屬性表具有嚴格的順序,並且只要屬性的名稱不與已有的屬性名稱重複,任何人實現的編譯器可以向屬性表中寫入自己定義的屬性資訊。虛擬機器在執行時會忽略不能識別的屬性,為了能正確解析Class檔案,虛擬機器規範中預定義了虛擬機器實現必須能夠識別的9項屬性(預定義屬性已經增加到21項)
- 常見的屬性
屬性名稱 | 使用位置 | 含義 |
---|---|---|
Code | 方法表 | Java程式碼編譯成的位元組碼指令 |
ConstantValue | 欄位表 | final關鍵字定義的常量值 |
Deprecated | 類檔案、欄位表、方法表 | 被宣告為deprecated的方法和欄位 |
Exceptions | 方法表 | 方法丟擲的異常 |
InnerClasses | 類檔案 | 內部類列表 |
LineNumberTale | Code屬性 | Java原始碼的行號與位元組碼指令的對應關係 |
LocalVariableTable Code屬性 | 方法的區域性變數描述 | |
SourceFile | 類檔案 | 原始檔名稱 |
Synthetic | 類檔案、方法表、欄位表 | 標識方法或欄位是由編譯器自動生成的 |
對於每個屬性,它的名稱需要從常量池中引用一個CONSTANT_utf8_info型別的常量類表示,而屬性值的結構則是完全自定義的,只需要通過一個u4的長度屬性區說明屬性值所佔用的位數即可.
- 屬性表定義的結構
型別 | 名稱 | 數量 |
---|---|---|
u2 | attribute_name_index | 1 |
u2 | attribute_length | 1 |
u1 | info | attribute_length |
一:Code屬性
java程式方法體中的程式碼經過javac編譯器處理後,最終變為位元組碼指令儲存在Code屬性內。Code屬性出現在方法表的屬性集合中,抽象類和介面不存在code屬性。
code屬性是class類檔案中最重要的屬性。class檔案可以分為程式碼(code,方法體裡面的Java程式碼)和元資料(Metadata,包括類,欄位,方法定義及其他資訊)兩部分,code屬性描述程式碼,其他資料項都用於描述元資料。
- code屬性表結構
型別 | 名稱 | 數量 |
---|---|---|
u2 | attribute_name_index | 1 |
u4 | attribute_length | 1 |
u2 | max_stack | 1 |
u2 | max_locals | 1 |
u4 | code_length | 1 |
u1 | code | code_length |
u2 | exception_table_length | 1 |
exception_info | exception_table | exception_length |
u2 | attributes_count | 1 |
attribute_info | attributes | attributes_count |
- Class類檔案中對應的code屬性程式碼
- attribute_name_index
指向CONSTANT_Utf8_info型常量的索引,常量值規定為”Code“,代表了該屬性的屬性名稱。測試用例中值為0x0009,為常量池中的第九項。
#9 = Utf8 Code
- attribute_length
屬性值的長度,用8個位元組表示,測試用例中值為:0x00000006表示Code屬性值的位元組長度為47。
- max_stack
所需運算元棧的深度的最大值,方法執行的任何時刻,運算元棧都不會超過這個深度。虛擬機器執行時需要根據這個值分配棧幀。
測試用例中為:0x0001,說明需要的最大深度為1,沒有遞迴。
- max_locals
代表區域性變量表所需的儲存空間,單位為Slot(插槽),Slot是虛擬機器為區域性變數分配記憶體空間使用的最小單位。長度不超過32位的資料型別佔用1個Slot(byte,char,float,int,short,boolean,returnAddress),64位的資料型別(long和double)佔用2個Slot。Slot可以重用。當代碼執行超過區域性變數的作用域時,Solt可以被其他區域性變數使用。
測試用例中為:0x0001,說明需要的區域性變數槽位為1 - code_length和code
這兩個用來儲存java源程式編譯後生成的位元組碼指令。code_lenth代表位元組碼長度(u4),code用於儲存位元組碼指令的一系列位元組流。每個位元組指令是一個u1資料型別(1bit).虛擬機器讀取到一個一個位元組碼時,就可以找出對應的這個位元組碼是什麼指令。java虛擬機器最多可以有256條指令,現在有200多條指令。
位元組碼區域長度為0x00000005,虛擬機器讀取到後會順序依次的讀取之後的5個位元組,並根據位元組碼指令表翻譯為對應的位元組碼指令。
過程為
1:讀入2A,對應指令為aload_0,將低0個Slot槽位為reference型別的本地變數推送到棧的頂端。
2:讀入B7,對應指令為invokespecial,將棧頂的reference型別的資料所指向的物件作為方法的接收者,呼叫此物件的例項構造方法。這條指令帶有一個u2型別的引數,為具體呼叫的哪一個方法,指向常量池中一個
CONSTANT_Methodref_info型別常量,即此方法的符號應用。
3:讀入00 0A,0x000A對應為常量池第10個常量,為例項構造器init方法的符號引用
#10 = Methodref #3.#11 // java/lang/Object."<init>":()V
讀入B1,對應指令為return,含義為返回此方法,返回值為void。這條指令執行完後當前方法結束。
屬性表對應的方法表完整程式碼
{
public cn.yuli.jvm.TestClass();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcn/yuli/jvm/TestClass;
public int inc();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: getfield #18 // Field m:I
4: iconst_1
5: iadd
6: ireturn
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 7 0 this Lcn/yuli/jvm/TestClass;
}
這兩個為例項構造器方法init()和inc(),locals和Args_size=1是應為有this引用,區域性變數第一槽位儲存的是本物件的this引用,如果方法定義為static,locals就為0了。
- exception_table_length和exception_info
exception_table_length是u2型別,4個位元組。異常表對Code屬性來說不是必須存在, 在本例項中為0x0000,說明不存在異常表。
- attributes_count和attributes
為Code表中包含的其他屬性,如:
LineNumberTable屬性,用於描述java原始碼行號和位元組碼行號之間的對應關係。
LocalVariableTable屬性,使用者描述棧中區域性變量表中的變數和java原始碼中定義的變數的關係。
繼續讀位元組碼檔案,0x0000之後是0x0002,說明Code錶帶有兩個屬性。第一個屬性是0x000C,轉換為10進製為12查常量表為
#12 = Utf8 LineNumberTable
說明是LineNumberTable屬性,根據LineNumberTable屬性結構,接下來為u4型別的長度描,0x0000006,為6位bit。
接下來2位為0x0001,即該line_number_table中只有一個line_number_info表,位元組碼行號start_pc為0x0000,l原始碼行號ine_number為0x0006,LineNumberTable屬性結束。
相關推薦
jvm探祕五:Class類檔案結構之屬性表
概述 在Class檔案、欄位表和方法表都可以攜帶自己的屬性資訊,這個資訊用屬性表進行描述,用於描述某些場景專有的資訊。 與Class檔案中其它資料項對長度、順序、格式的嚴格要求不同,屬性表集合不要求其中包含的屬性表具有嚴格的順序,並且只要屬性的名稱不與已
深入理解JVM虛擬機器(四):Class類檔案結構(二)
屬性表在前面的講解中出現多次,在Class檔案、欄位表、方法表都可以攜帶自己的屬性表集合,用於描敘某些場景專有的資訊。為了正確解析Class檔案,《Java虛擬機器規範(第二版)》中預定義了9項虛擬機器實現應當識別的屬性。然而在最新的《Java虛擬機器規範(Java SE7)》中屬性表已經增
【深入Java虛擬機器】之二:Class類檔案結構
平臺無關性 Java是與平臺無關的語言,這得益於Java原始碼編譯後生成的儲存位元組碼的檔案,即Class檔案,以及Java虛擬機器的實現。不僅使用Java編譯器可以把Java程式碼編譯成儲存位元組碼的Class檔案,使用JRuby等其他語言的編譯器也可以把程式
Class類檔案結構之ConstantValue屬性
程式設計過程中經常用的static,final關鍵字,也經常聽到同事談起這些詞,到底他們怎麼樣呢,jvm中class類檔案結構可以找到答案。 ConstantValue屬性 ConstantValue屬性的作用是通知虛擬機器自動為靜態變數賦值,只有被stat
JVM虛擬機器 - Class類檔案結構
JVM虛擬機器 - Class類檔案結構 概述 Class檔案是一組以8位位元組為基礎單位的二進位制流,各個資料專案嚴格按照順序緊湊地排列在Class檔案之中,中間沒有新增任何分隔符,這使得整個Class檔案中儲存的內容幾乎都是程式執行的必要資料。當遇到需要佔用8位位元組以上空間的資
如何學好JVM征服面試官?一篇Class 類檔案結構你還不會嗎?
Java 跨平臺的基礎 各種不同平臺的虛擬機器與所有平臺都
Java Class類檔案結構
平臺無關性 Java是與平臺無關的語言,這得益於Java原始碼編譯後生成的儲存位元組碼的檔案,即Class檔案,以及Java虛擬機器的實現。不僅使用Java編譯器可以把Java程式碼編譯成儲存位元組碼的Class檔案,使用JRuby等其他語言的編譯器也可以把程式程式碼編譯成Class檔案,虛擬機
Class 類檔案結構
> 本文部分摘自《深入理解 Java 虛擬機器第三版》 ## 概述 我們知道,Java 具有跨平臺性,其實現基礎就是虛擬機器和位元組碼儲存格式。Java 虛擬機器不與 Java 語言繫結,只與 Class 檔案所關聯。Java 虛擬機器作為一個通用的、與機器無關的執行平臺,任何語言都可以將 Jav
深入理解JVM(五):類檔案結構
今天我們來介紹一下Class類檔案結構 1.概述 計算機雖然只能識別0和1,但是越來越多的程式語言選擇了與作業系統和機器指令集無關的、平臺中立的格式作為程式編譯後的儲存格式。Java虛擬機器不和包括Java在內的任何語言繫結,只與“class檔案”這種特定的二進
深入理解JVM之五:類檔案結構
前言 我們平時在DOS介面中往往需要執行先執行javac命令,這個命令的直接結果就是產生相應的class檔案,然後基於這個class檔案才可以真正執行程式得到結果。自然。這是Java虛擬機器的功勞,那麼是不是Java虛擬機器只能編譯.java的原始檔呢?答案是
【JVM】class類檔案的結構
作為Java程式猿,我們知道,我們寫好的.java 原始碼,最後會被Java編譯器編譯成字尾為.class的檔案,該型別的檔案是由位元組組成的檔案,又叫位元組碼檔案。那麼,class位元組碼檔案裡面到底是有什麼呢?它又是怎樣組織的呢?讓我們先來大概瞭解一下他的組成結構吧。
深入理解JVM虛擬機器:(三)類檔案結構(上)
前言 在上一篇深入理解JVM虛擬機器:(二)垃圾收集器概述 文章中,我們瞭解了Java虛擬機器中垃圾收集器的種類以及垃圾回收的方式等,這一篇,我們將去了解一下Java中類檔案的內部構造,由於這一章比較抽象,因此將會分為兩篇文章進行講解。 概述 程式碼編譯的
Java中的類檔案結構之一:如何分析一個.class檔案的二進位制碼內容
該文為作者原創,請轉載者註明出處 以下為一個Java類--Temp4Test package com.demo; public class Temp4Test extends Temp3Test { private int i = 1;
【搞定Jvm面試】 面試官:談談 JVM 類檔案結構的認識
類檔案結構 一 概述 在 Java 中,JVM 可以理解的程式碼就叫做位元組碼(即副檔名為 .class 的檔案),它不面向任何特定的處理器,只面向虛擬機器。Java 語言通過位元組碼的方式,在一定程度上解決了傳統解釋型語言執行效率低的問題,同時又保留了解釋型語言可移植的特點。所以 Java 程式執行時比較高
【深入Java虛擬機】之二:Class類文件結構
本質 拒絕 處理 implement align 默認值 改變 占用 至少 平臺無關性 Java是與平臺無關的語言,這得益於Java源代碼編譯後生成的存儲字節碼的文件,即Class文件,以及Java虛擬機的實現。不僅使用Java編譯器可以把Java代碼編譯成存儲字節
「深入Java虛擬機(2)」:Class類文件結構
1.5 trac 三種 type 類構造 face 方法 class throw Java是與平臺無關的語言,這得益於Java源代碼編譯後生成的存儲字節碼的文件,即Class文件,以及Java虛擬機的實現。不僅使用Java編譯器可以把Java代碼編譯成存儲字節碼的Class
JVM系列第5講:位元組碼檔案結構
溫馨提示:此篇文章長達兩萬字,圖片50多張,內容非常多,建議收藏後再看。 前面我們說到 Java 虛擬機器使用位元組碼實現了跨平臺的願景,無論什麼系統,我們都可以使用 Java 虛擬機器解釋執行位元組碼檔案。但其實位元組碼是有一套規範的,而規定位元組碼格式的就是《Java 虛擬機器規範》。《Ja
讀書筆記 ---- 《深入理解Java虛擬機器》---- 第5篇:類檔案結構
上一篇:虛擬機器效能監控與故障處理工具:https://blog.csdn.net/pcwl1206/article/details/84197113 第5篇:類檔案結構 開篇說明:本文的重點就是類檔案結構,只需要清楚Class檔案格式中的各名稱的實際意義就行,不用對具體名稱下的細節進行深究
深入理解JVM(六)——類檔案結構——code
Code Java程式中方法體中的程式碼經過Javac編譯器處理之後,最終變成位元組碼指令儲存在Code屬性內。 Code屬性出現在方法表的屬性集合之中,但不是所有的方法表都必須有,譬如介面或者抽象類。 Code是Class檔案中最重要的一個屬性,如果把一個Java程式中的資訊分
深入理解JVM(六)——類檔案結構
Java誕生之初就有的口號,Write Once,Run Anywhere Java規範分為Java語言規範和Java虛擬機器規範,Java實現平臺無關性的基礎是虛擬機器和位元組碼儲存格式,Java虛擬機器不與包括Java在內的任何語言繫結,它只與Class檔案這種特定的二進位制檔案格式