JVM系列之七:位元組碼執行
Javap
– class檔案反彙編工具
– javap –verbose Calc
java 檔案
public class Calc {
public int calc() {
int a = 500;
int b = 200;
int c = 50;
return (a + b) / c;
}
}
編譯後Class檔案
public int calc();
Code:
Stack=2, Locals=4, Args_size=1
0: sipush 500
3: istore_1
4: sipush 200
7: istore_2
8: bipush 50
10: istore_3
11: iload_1
12: iload_2
13: iadd
14: iload_3
15: idiv
16: ireturn
}
簡單的位元組碼執行過程
以上節的例子為例:
首先將500壓人運算元棧,然後將運算元棧彈出到Int型變數1
將200壓人運算元棧,然後將運算元棧彈出到Int型變數2
將50壓人運算元棧,然後將運算元棧彈出到Int型變數3
將Int型變數1的值載入到運算元棧,將Int型變數2的值載入到運算元棧
對運算元棧裡面的值做整數的加法操作,之後將Int型變數3的值載入到運算元棧
對運算元棧裡面的值做整數的除法操作,將運算元棧裡的值作為方法的返回值返回
常用的位元組碼
常量入棧
– aconst_null null物件入棧
– iconst_m1 int常量-1入棧
– iconst_0 int常量0入棧
– iconst_5
– lconst_1 long常量1入棧
– fconst_1 float 1.0入棧
– dconst_1 double 1.0 入棧
– bipush 8位帶符號整數入棧
– sipush 16位帶符號整數入棧
– ldc 常量池中的項入棧
區域性變數壓棧
– xload(x為i l f d a)
· 分別表示int,long,float,double,object ref
– xload_n(n為0 1 2 3)
– xaload(x為i l f d a b c s)
· 分別表示int, long, float, double, obj ref ,byte,char,short
n 從陣列中取得給定索引的值,將該值壓棧
· iaload
· 執行前,棧:..., arrayref, index
· 它取得arrayref所在陣列的index的值,並將值壓棧
· 執行後,棧:..., value
出棧裝載入區域性變數
– xstore(x為i l f d a)
· 出棧,存入區域性變數
– xstore_n(n 0 1 2 3)
· 出棧,將值存入第n個區域性變數
– xastore(x為i l f d a b c s)
· 將值存入陣列中
· iastore
· 執行前,棧:...,arrayref, index, value
· 執行後,棧:...
· 將value存入arrayref[index]
通用棧操作(無型別)
– Nop
· 空指令
– pop
· 彈出棧頂1個字長
– dup
· 複製棧頂1個字長,複製內容壓入棧
型別轉化(舉例)
– i2l
· 將int轉為long
· 執行前,棧:..., value
· 執行後,棧:...,result.word1,result.word2
· 彈出int,擴充套件為long,併入棧
– i2f
– l2i
– l2f
– l2d
– f2i
– f2d
整數運算
– iadd
– ladd
– isub
– lsub
– idiv
– ldiv
– imul
– lmul
– iinc
浮點運算
– fadd
– dadd
– fsub
– dsub
– fdiv
– ddiv
– fmul
– dmul
物件操作指令
– new
– getfield
– putfield
– getstatic
– putstatic
條件控制
– ifeq 如果為0,則跳轉
· 引數 byte1,byte2
· value出棧 ,如果棧頂value為0則跳轉到(byte1<<8)|byte2
· 執行前,棧:...,value
· 執行後,棧:...
– ifne 如果不為0,則跳轉
– iflt 如果小於0 ,則跳轉
– ifge 如果大於0,則跳轉
– if_icmpeq 如果兩個int相同,則跳轉
方法呼叫
– invokevirtual
– invokespecial
– invokestatic
– invokeinterface
– xreturn(x為 i l f d a 或為空)
JIT及其相關引數
· 位元組碼執行效能較差,所以可以對於熱點程式碼編譯成機器碼再執行,在執行時的編譯,叫做JIT Just-In-Time
· JIT的基本思路是,將熱點程式碼,就是執行比較頻繁的程式碼,編譯成機器碼。
JIT
當虛擬機發現某個方法或程式碼塊執行特別頻繁時,就會把這些程式碼認定為“Hot Spot Code”(熱點程式碼),為了提高熱點程式碼的執行效率,在執行時,虛擬機器將會把這些程式碼編譯成與本地平臺相關的機器碼)
熱點程式碼
呼叫的方法。被多次呼叫的迴圈體。
兩個計數器
方法呼叫計數器:方法呼叫次數
回邊計數器:方法內迴圈次數
相關引數
– -XX:CompileThreshold=1000
· 通過JIT編譯器,將方法編譯成機器碼的觸發閥值,可以理解為呼叫方法的次數,例如調1000次,將方法編譯為機器碼。
· 預設值為1000
– -Xint
· 解釋執行
– -Xcomp
· 全部編譯執行
– -Xmixed
預設,混合
相關推薦
JVM系列之七:位元組碼執行
Javap– class檔案反彙編工具– javap –verbose Calcjava 檔案public class Calc {public int calc() {int a = 500;int b = 200;int c = 50;return (a + b) / c
Java併發程式設計系列之七:正確終止與恢復執行緒
前面提到了stop()、suspend()等方法在終止與恢復執行緒的弊端,那麼問題來了,應該如何正確終止與恢復執行緒呢?這裡可以使用兩種方法:interrupt()方法和使用boolean變數進行控制。 在使用interrupt方法之前,有必要介紹一下中斷以及
JVM--詳解虛擬機器位元組碼執行引擎之靜態連結、動態連結與分派
這篇部落格主要帶你認識何謂靜態連結、動態連結。並且會講述JVM中分派的知識,讓你對Java中的多型實現機制有一個淺顯的認識。 前言 從接觸Java語言的第一天起,往後,我相信你一定聽過什麼動態連結啊,動態擴充套件啊,靜態連結啊,它和C++相比有哪些優
JVM之虛擬機器位元組碼執行引擎(八)
虛擬機器的執行引擎是自己實現的,有自己的指令集和執行引擎的結構體系,能夠執行那些不被硬體直接支援的指令集格式。(物理機執行引擎是建立在處理器、硬體、指令集和作業系統層面)。 但在不同的虛擬機器實現裡,執行引擎在執行java程式碼的時候,可能會解釋執行和編譯執行
Office 365 系列之七:安裝 Office 365 ProPlus
office365 安裝office 安裝在線office 在前幾篇文章中已經完成了O365用戶的手動創建和批量導入並分配對應的許可。既然用戶已經具備使用這個服務的許可了,今天我們就一起來看看如何去使用O365,和本地的Office又有何差別,然後介紹使用即點即用技術安裝 Office 3
Exchange 2013系列之七:部署後任務
Exchange AD Windows 到昨天為止,Exchange 的部署基本上就完成了,今天我們來看看部署完成後還需要做一些什麽工作。 一、發送連接器 默認情況下,Exchange 2013是不允許將郵件發送到域外部的,如果想要發送外部郵件,需要建立一個發送連接器。打開ECP管理界面,導航至
JVM系列之三:型別的生命週期
此篇文章主要介紹從一個Java型別(類或者介面)的生命週期(從它進入虛擬機器到退出)開始階段的裝載、連線與初始化,以及佔Java型別宣告週期絕大部分時間的物件例項化、垃圾收集和物件終結,然後是Java型別生命週期的結束,也就是從虛擬機器中解除安裝。 型別裝載、連線與初始化 Java虛擬機器通過裝載、連
深入理解JVM虛擬機器(五):位元組碼指令簡介
Java 虛擬機器的指令由一個位元組長度的、代表著某種特定操作含義的數字(稱為操作碼)以及跟隨其後的零至多個代表此操作所需引數(運算元)而構成。由於 Java 虛擬機器採用面向運算元棧而不是暫存器的架構,所以大多數的指令都不包含運算元,只有一個操作碼。 1. 位元組碼與資料型別
skyfans之每天一個Liunx命令系列之七:cpuinfo、meminfo
首先宣告:非常抱歉,昨天懶了,沒有更新基本命令的內容,主要原因是一直在看IG的比賽,看完之後3:0的戰績使朋友們高興的出去喝酒了,那看的是真解氣啊。IG算是幫RNG報仇了。但是,從IG整改隊伍的身上,我想RNG也應該多學學某種東西。好廢話不多說,開始正題(我只是
敏捷開發產品管理系列之七:Product Owner團隊
目的在之前的《Product Servant》一篇中曾經提到,作為產品經理或產品總監,都應該有自己的方式來根據市場和使用者情況來管理產品的走向,其中前者更傾向於具體的功能,而後者則更傾向於市場方向的競爭力;前者要求細節,後者要求高度。那麼,這兩個人到底誰是傳統意義上的Pro
logback系列之七:繼承RollingFileAppender,儲存自定義檔名的日誌
繼承類:package com.hk3t.air.system.log; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos
深入理解Tomcat系列之七:詳解URL請求
前言 這裡分析一個實際的請求是如何在Tomcat中被處理的,以及最後是怎麼樣找到要處理的Servlet的?當我們在瀏覽器中輸入http://hostname:port/contextPath/servletPath,前面的hostname與port用於建立tc
算法系列之七:愛因斯坦的思考題(下)
CheckGroupRelation()函式需要根據當前組group的位置進行適當的處理,如果當前組是第一個組或最後一個組,則group的相鄰組只有一個,就是最靠近group的組,其它情況下group的相鄰組都是兩個。CheckGroupRelation()函式的實現如下:
深入理解Java虛擬機器之虛擬機器位元組碼執行引擎
執行引擎是java虛擬機器最核心的組成部分之一。 物理機的執行引擎是建立在處理器、硬體、指令集和作業系統層面上的,而虛擬機器的執行引擎是由自己實現的,可以自行制定指令集與執行引擎的結構體系,並且能夠執行那些硬體不直接支援的指令集格式。 執行引擎在執行Java
VALSE2017系列之七:視覺與語言領域年度進展概述
點選上方“深度學習大講堂”可訂閱哦!編者按:視覺和自然語言處理長期以來是兩個獨立的課題,而深度學
ZooKeeper系列之七:ZooKeeper命令列工具
當啟動 ZooKeeper 服務成功之後,輸入下述命令,連線到 ZooKeeper 服務: zkCli.sh –server 10.77.20.23:2181 連線成功後,系統會輸出 ZooKeeper 的相關環境以及配置資訊,並在螢幕輸出“ Welcome to
算法系列之七:愛因斯坦的思考題(上)
這是一個很有趣的邏輯推理題,傳說是愛因斯坦提出來的,他宣稱世界上只有2%的人能解出這個題目,傳說不一定屬實,但是這個推理題還是很有意思的。題目是這樣的,據說有五個不同顏色的房間排成一排,每個房間裡分別住著一個不同國籍的人,每個人都喝一種特定品牌的飲料,抽一種特定品牌的煙,養
kubernetes系列之七:一些將legacy應用遷移到kubernetes的經驗
一、前言基於kubernetes的應用實際上是微服務在container方向的例項,所以很多微服務的設計原則在kubernetes框架內依然具有參考價值,比如The Twelve Factors。在legacy應用從基於VM的部署向基於kubernetes部署的遷移過程中,需
深入理解Java虛擬機器----(七)位元組碼執行引擎
位元組碼執行引擎是執行引擎是最重要的一部分,概念模型的總體外觀是一致的:輸入位元組碼,過程是位元組碼解析的等效過程,輸出結果。不同的虛擬機器有不同的具體實現,大體有解釋執行和編譯執行兩種選擇。 執行時棧幀結構: 棧楨在虛擬機器棧中,是支援方法呼叫和執行的結
Java位元組碼詳解系列之二--解析位元組碼
1、javap檢視位元組碼內容上文介紹了位元組碼的結構,本文主要通過一個簡單的例子說明class位元組碼的每一個欄位。package com.zcm.test; import java.io.Serializable; public class SourceTest im