摘要:我們對做下拆解,一個常量,一個變量。因為帶有兩個參數(shù),所以在局部變量索引索引為的位置插入,在索引為的位置插入。
前言
這段時間一直在看JVM相關(guān)的書籍,雖然有點難,至少到目前為止還沒有放棄。寫這篇文章的目的:當(dāng)做自己這段時間學(xué)習(xí)的小回顧。本章主要通過幾個代碼片段,分析下局部變量表與操作數(shù)棧之間的數(shù)據(jù)傳遞關(guān)系,重點講解iload,istore,iconst_
局部變量表:每個棧幀內(nèi)部都包含一組稱為局部變量表的變量列表
操作數(shù)棧:每個棧幀內(nèi)部都包含一個操作數(shù)棧
iconst_0:把int型的0值壓入操作數(shù)棧
iload:將一個局部變量加載到操作數(shù)棧上
istore:將一個數(shù)值從操作數(shù)棧上存儲到局部變量表中
iadd:返回棧頂?shù)膬蓚€元素做加法運算,并加結(jié)果壓棧
如何使用dos查看字節(jié)碼文件首先通過dos進入TestApp.class所在的目錄,然后運行命令javap -c TestApp,即可看到編譯后的字節(jié)碼文件
程序片段一以下是一個java源代碼
public void test1(){ int c=0; }
編譯后的字節(jié)碼
public void test1(); Code: 0: iconst_0 1: istore_1 2: return
代碼分析
因為test1()是一個實例方法,所以在局部變量表中,索引為0的位置會保存該方法所在類的引用(this),所以才會出現(xiàn)istore_1而不是istore_0。
我們對int c = 0做下拆解,一個常量0,一個變量c。
0: iconst_0 //將常量0壓入操作數(shù)棧 1: istore_1 //將棧頂出棧,即c=0 2: return //因為是void,沒有返回值程序片段二
Java源代碼如下
public static void test2(){ int c=0; }
編譯后的字節(jié)碼文件
public static void test2(); Code: 0: iconst_0 1: istore_0 2: return
分析
因為test2()是一個靜態(tài)的方法,不會在局部變量表中插入任何數(shù)據(jù)。所以你看到的是istore_0而不是像程序片段一中的istore_1。其他分析跟程序片段一相同
程序片段三java源代碼
public int test3(){ int c=0; return c; }
編譯后的字節(jié)碼
public int test3(); Code: 0: iconst_0 1: istore_1 2: iload_1 3: ireturn
分析
0: iconst_0 //將常量0壓棧 1: istore_1 //將棧頂出棧,及c=0 2: iload_1 //將變量c壓入棧頂 3: ireturn //返回棧定元素程序片段四
Java源代碼
public int test4(int a,int b){ int c=0; return a+b; }
編譯后的字節(jié)碼
public int test4(int, int); Code: 0: iconst_0 1: istore_3 2: iload_1 3: iload_2 4: iadd 5: ireturn
** 分析
因為test4(int a,int b)是實例方法,所以在局部變量表索引為0的位置會插入this。
因為test4(int a,int b)帶有兩個參數(shù),所以在局部變量索引索引為1的位置插入a,在索引為2的位置插入b。
0: iconst_0 //將常量0壓棧 1: istore_3 //將棧頂出棧,即c=0,將c存儲到局部變量表索引為3的位置 2: iload_1 //將局部變量表中索引為1的變量壓棧,即a壓棧 3: iload_2 //將局部變量表中索引為2的變量壓棧,即b壓棧 4: iadd //將棧頂兩個元素出棧,做加法,然后把結(jié)果再入棧(即a,b出棧,將a+b入棧) 5: ireturn //返回a+b的值程序片段五
java源代碼
public int test5(int a,int b){ int c=0; c= a+b; return c; }
編譯后的字節(jié)碼
public int test5(int, int); Code: 0: iconst_0 1: istore_3 2: iload_1 3: iload_2 4: iadd 5: istore_3 6: iload_3 7: ireturn
分析
0: iconst_0 //將常量0壓棧 1: istore_3 //將棧頂出棧,及c=0 2: iload_1 //從局部變量表中加載索引為1的變量壓棧,即a壓棧 3: iload_2 //從局部變量表中加載索引為2的變量壓棧,即b壓棧 4: iadd //將棧頂兩個元素出棧,做加法,然后將結(jié)果壓棧,及a+b壓棧 5: istore_3 //將棧頂元素出棧,并保存到局部變量表中,即c=a+b 6: iload_3 //從局部變量表中加載索引為3的變量壓棧,即c壓棧 7: ireturn //返回棧頂元素,即返回c
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/66815.html
摘要:學(xué)習(xí)能更深入的理解這門語言,能理解語言底層的執(zhí)行過程,深入到字節(jié)碼層次。 目錄 ? 前言 程序的運行 1.JVM類加載機制 ①一般在什么情況下會去加載一個類?也就是說,什么時候.class字節(jié)碼文件中加載這個類到JVM內(nèi)存里來? ②驗證、準(zhǔn)備、初始化 ③初始化 2.類加載器和雙親委派機制 ...
摘要:運行時數(shù)據(jù)區(qū)域的學(xué)習(xí),是學(xué)習(xí)以及機制的基礎(chǔ),也是深入理解對象創(chuàng)建及運行過程的前提。了解內(nèi)存區(qū)域劃分,是學(xué)習(xí)概念的前提。 Java 運行時數(shù)據(jù)區(qū)域的學(xué)習(xí),是學(xué)習(xí) jvm 以及 GC 機制的基礎(chǔ),也是深入理解 java 對象創(chuàng)建及運行過程的前提。廢話不多說,直接進入正題: 一張圖總結(jié) showImg(https://segmentfault.com/img/bVOMAn?w=685&h=5...
摘要:下文將從字節(jié)碼的角度,分析中基本類型傳參和對象傳參。主函數(shù)執(zhí)行時,操作棧會推入主函數(shù)棧幀,其中包含了主函數(shù)的局部變量表,字節(jié)碼,返回值等信息。主函數(shù)的棧幀會被推入棧,成為當(dāng)前操作棧。 個人網(wǎng)站地址: http://kailuncen.me/2017/06/0... 一個小問題 在開源中國看到這樣一則問題 https://www.oschina.net/quest...,其中的變量a前...
摘要:一內(nèi)存區(qū)域虛擬機在運行時,會把內(nèi)存空間分為若干個區(qū)域,根據(jù)虛擬機規(guī)范版的規(guī)定,虛擬機所管理的內(nèi)存區(qū)域分為如下部分方法區(qū)堆內(nèi)存虛擬機棧本地方法棧程序計數(shù)器。前言 在JVM的管控下,Java程序員不再需要管理內(nèi)存的分配與釋放,這和在C和C++的世界是完全不一樣的。所以,在JVM的幫助下,Java程序員很少會關(guān)注內(nèi)存泄露和內(nèi)存溢出的問題。但是,一旦JVM發(fā)生這些情況的時候,如果你不清楚JVM內(nèi)存的...
摘要:而熱部署技術(shù)能夠幫助開發(fā)人員減少重新部署的等待時間。本文的目的為調(diào)研熱部署的技術(shù)現(xiàn)狀及其對開發(fā)效率的幫助,并簡單梳理其技術(shù)實現(xiàn)的難點。熱部署技術(shù)總結(jié)熱部署目前有多種技術(shù)實現(xiàn)官方開源商業(yè)。 開發(fā)、自測、聯(lián)調(diào)期間代碼可能會被頻繁地修改,通常即使只增加了一行代碼,都需要重啟容器以檢查執(zhí)行效果。而熱部署技術(shù)能夠幫助開發(fā)人員減少重新部署的等待時間。本文的目的為調(diào)研熱部署的技術(shù)現(xiàn)狀及其對開發(fā)效率的...
閱讀 2284·2021-09-07 09:58
閱讀 3473·2019-08-30 14:07
閱讀 1354·2019-08-29 12:32
閱讀 724·2019-08-29 11:06
閱讀 3747·2019-08-26 18:18
閱讀 3810·2019-08-26 17:35
閱讀 1441·2019-08-26 11:35
閱讀 672·2019-08-26 11:35