在上文中,咱們講解了 Class 文件中的文件標識,常量池等內容。在本文中,咱們就詳細說一下剩下的指令集內容,闡述其分別表明了什麼含義,以及 JVM 團隊這樣設計的意義。java
JVM 指令設計爲僅有一個字節長度,由操做碼和緊隨其後的零至多個操做數來構成。編程
這裏說到 JVM 的指令僅有一個字節,這意味着 JVM 在操做超過一個字節長度的數據時,須要在運行時重建出多字節數據類型的具體數據結構,例如 Long 等。這會致使這個操做不是原子操做,在高併發的狀況下,就有可能會致使錯誤。segmentfault
因爲 JVM 的操做碼長度只有一個字節,所以設計指令的時候,須要考慮全部指令加起來不能超過一個字節長度,正因如此,有許多數據類型是沒有其對應的操做碼的,其操做的方式是將其數據類型進行向上轉型爲其餘的數據類型來參與運算。數組
例如大多數對於 boolean、byte、short 和 char 類型數據的操做,其實是將其轉換成 int 類型來處理的。數據結構
JVM 指令若是詳細來講的話有一百多個,在這裏所有展開來描述的,難免有流水帳的嫌疑,且價值不大,所以在本文中僅粗略描述一下,並找了一些關鍵的指令對其進行詳細拆解,若是讀者對其餘指令有興趣的話能夠自行 Google 或翻書學習。
所有指令的內容併發
加載和存儲指令:用於將數據在棧幀中的局部變量表和操做數棧之間轉移(棧幀的佈局放在之後的文章 JVM-內存佈局中進行介紹,在這裏讀者只要明白其是根據棧進行操做就能夠了)。eg:load,store;jvm
運算指令:對兩個操做數棧上的值進行計算並從新存入到操做棧頂。eg:add,sub,mul,div,rem,neg,shr,or,and,inc……;高併發
類型轉換指令:將一個值數據類型進行轉換爲其餘的類型。eg:x2x;佈局
對象建立與訪問指令:new,newarray(數組和類實例建立和操做是不一樣的);學習
操做數棧操做指令:直接操做操做數棧。eg:pop,swap;
控制轉移指令:有條件或無條件的控制 JVM 從指定的位置執行程序。(能夠簡單理解爲修改程序計數器中的值)。eg:if,goto……;
方法調用和返回指令:根據對象的實際類型進行虛方法分配,調用類方法,調用接口方法等。另外還有根據不一樣的返回類型的不一樣返回指令;
異常處理指令:目前異常處理在 JVM 內部是經過異常表來完成的;
Exception table: from to target type 0 8 14 Class java/lang/RuntimeException 0 8 29 any 14 23 29 any
from 行 到 to 行之間的字節碼指令若是出現了 type 以及其子類的類型錯誤,就跳轉到 target 行對應的字節碼指令進行執行;
PS:上面這段是 synchronized 關鍵字的本質含義,其具體的細節放到高併發編程系列文章中詳細來講。
經過 Class 文件這個中間文件,JVM 達成了語言無關性和平臺無關性兩個大突破,使得 Java 語言不只達到了「一次編寫,到處運行」,也使得其餘語言只要符合 JVM 規範,就能夠像 Java 同樣,達到超然物外的無關性。
文章在公衆號 「iceWang" 第一手更新,有興趣的朋友能夠關注公衆號,第一時間看到筆者分享的各項知識點,謝謝!筆芯!
本系列文章主要借鑑自《深刻分析 JavaWeb 技術內幕》和《深刻理解 Java 虛擬機- JVM 高級特性與最佳實踐》。