【Java】JVM位元組碼分析

changwan發表於2024-06-05

一、功能

1、工作原理

whiteboard_exported_image (1).png

2、解釋和執行

jvm本質上是執行在計算機上的程式,負責執行java位元組碼檔案

對位元組碼檔案中的指令,實時的解釋成機器碼,供計算機執行

3、記憶體管理

自動為物件、方法等分配記憶體

自動垃圾回收機制,回收不再使用的物件

4、 即時編譯

在java中每次執行都需要實時解釋位元組碼檔案成機器碼,導致效率較低、速度變慢。這麼做的原因是因為需要跨平臺,不同作業系統的java虛擬機器不同,解釋編譯的也不一樣,不同的虛擬機器會轉成當前作業系統的位元組碼。

即時編譯就是為了解決這個效能問題。JVM會識別熱點程式碼(短時間多次呼叫), 會主動最佳化並且解釋成機器碼 ,將這個機器碼儲存在記憶體中。下次如果呼叫這段熱點程式碼會直接從記憶體中取出呼叫。這樣就省略了一次解釋的步驟。這樣在某些情況下效能就會提升很大

二、解釋位元組碼

使用工具jclasslib工具檢視class位元組碼

class位元組檔案的標頭檔案的前四個位元組是檢驗檔案型別用的,class位元組檔案的標頭檔案為CAFEBABE

1、分析class檔案

public class HelloWorld {
    public static void main(String[] args) {
        int i = 0 ;
        int j = i+1;
        System.out.println(j);
    }
}

對應的.class位元組檔案為

 0 iconst_0    #將常量0放入運算元棧中
 1 istore_1    #將運算元棧頂的數值儲存到區域性變數表1的位置
 2 iload_1     #將區域性變數表1中的數複製到棧上
 3 iconst_1    #將常量1放入運算元棧中棧中
 4 iadd        #將棧中最上面兩個值進行相加,儲存到棧頂
 5 istore_2    #從棧中取出運算元放入區域性變數表中2號位置
13 return      #方法結束

whiteboard_exported_image.png

2、分析i++

public class HelloWorld {
    public static void main(String[] args) {
        int i = 0 ;
        i = i++; 
        System.out.println(i);
    }
}
 0 iconst_0       #將常量0放入運算元棧
 1 istore_1       #將棧頂元素取出儲存到區域性變數表1的位置
 2 iload_1        #將區域性變數表1位置的運算元複製到操作棧
 3 iinc 1 by 1    #將佈局變數表1的位置的值加1
 6 istore_1       #將棧頂元素取出儲存到區域性變數表1的位置
10 iload_1        #將佈局變數表1位置的運算元複製到運算元棧
14 return

結果輸出為0

3、分析++i

public class HelloWorld {
    public static void main(String[] args) {
        int i = 0 ;
        i = ++i; 
        System.out.println(i);
    }
}
 0 iconst_0       #將常量0放入運算元棧
 1 istore_1       #將棧頂元素取出儲存到區域性變數表1的位置
 2 iinc 1 by 1    #將佈局變數表1的位置的值加1
 5 iload_1        #將佈局變數表1位置的運算元複製到運算元棧
 6 istore_1       #將棧頂元素取出儲存到區域性變數表1的位置
10 iload_1        #將佈局變數表1位置的運算元複製到運算元棧
14 return

輸出結果為1

相關文章