由于對(duì)于不同的處理器(ARM/X86)內(nèi)部的寄存器的設(shè)計(jì)架構(gòu)是不同的,Java 語(yǔ)言為了實(shí)現(xiàn) “Write once Run everywhere” 的口號(hào),內(nèi)部的指令都是通過(guò)棧來(lái)實(shí)現(xiàn)的。
成都創(chuàng)新互聯(lián)公司成立10年來(lái),這條路我們正越走越好,積累了技術(shù)與客戶資源,形成了良好的口碑。為客戶提供網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、網(wǎng)站策劃、網(wǎng)頁(yè)設(shè)計(jì)、空間域名、網(wǎng)絡(luò)營(yíng)銷、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。網(wǎng)站是否美觀、功能強(qiáng)大、用戶體驗(yàn)好、性價(jià)比高、打開(kāi)快等等,這些對(duì)于網(wǎng)站建設(shè)都非常重要,成都創(chuàng)新互聯(lián)公司通過(guò)對(duì)建站技術(shù)性的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究為客戶提供一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進(jìn)步。棧是程序的運(yùn)行時(shí)的單位,而對(duì)于堆更像是數(shù)據(jù)的存儲(chǔ)單位。
棧:程序運(yùn)行時(shí)調(diào)用的各種功能性的方法處理解決數(shù)據(jù)問(wèn)題
堆:用于存放數(shù)據(jù),比如創(chuàng)建的對(duì)象,靜態(tài)的變量
關(guān)于程序的方法的棧幀解讀創(chuàng)建一個(gè)類如下代碼所示:
public class MyStackTest {public static void main(String[] args) {int number = 10;
double num = 20.0d;
Date date = new Date();
System.out.println("Hello World!!!");
}
}
通過(guò) jcalsslib 工具查看編譯過(guò)的 class 文件
對(duì)于當(dāng)前的 MyStackTest.class 類文件中在方法中可以看到有兩個(gè)文件
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-AYtDQ0ZT-1673321219762)(關(guān)于棧的存儲(chǔ)結(jié)構(gòu)與運(yùn)行原理分析.assets/image-20230110112111380.png)]
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-qAywoO6K-1673321219762)(關(guān)于棧的存儲(chǔ)結(jié)構(gòu)與運(yùn)行原理分析.assets/image-20230110112145675.png)]
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-5iZ5ULVV-1673321219763)(關(guān)于棧的存儲(chǔ)結(jié)構(gòu)與運(yùn)行原理分析.assets/image-20230110112440601.png)]
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-62z0uSat-1673321219764)(關(guān)于棧的存儲(chǔ)結(jié)構(gòu)與運(yùn)行原理分析.assets/image-20230110112541026.png)]
main方法解析對(duì)于 main 方法
名稱: 地址索引為 #18 方法名
描述符: 地址索引為 #19 形參為 java.lang.String 包路徑下的 L (引用數(shù)據(jù)類型) 為 [(數(shù)組) String 返回值類型 V(void)
訪問(wèn)標(biāo)志:[public static]
操作數(shù)棧大深度:2 (與數(shù)據(jù)的類型有關(guān)是固定的 32bit的類型占用一個(gè)棧單位 64bit的類型占用兩個(gè)棧單位)
局部變量大槽數(shù): 5 (局部變量的個(gè)數(shù),一個(gè)局部變量占用棧幀的一個(gè)槽位)
字節(jié)碼長(zhǎng)度:表示字節(jié)碼所占用的行數(shù)
比如該類中的 main 占用 25 行
0 bipush 10
2 istore_1
3 ldc2_w #2<20.0>6 dstore_2
7 new #410 dup
11 invokespecial #5: ()V>14 astore 4
16 getstatic #619 ldc #721 invokevirtual #824 return
第一部分:
? [0]LineNumberTable
? Nr. 表示局部變量的所占槽位置
? 起始PC 字節(jié)碼所在行號(hào)
? 行號(hào) 在源代碼中的行號(hào)
第二部分:
? [1] LocalVariableTable
? Nr. 表示局部變量的所占槽位
? 起始PC 字節(jié)碼所在行號(hào) 該局部變量的起始作用位置
? 長(zhǎng)度 25 + 0 = 25 (表示整個(gè)該方法的整個(gè)字節(jié)碼的長(zhǎng)度) 該字節(jié)碼的結(jié)束作用位置
? 序號(hào) 字節(jié)碼
? 名字 局部變量
? 起始PC + 長(zhǎng)度 = 局部變量的作用域范圍
局部變量的重復(fù)利用槽 一個(gè)局部變量占用一個(gè)槽位
局部變量表實(shí)際上在我們的內(nèi)存結(jié)構(gòu)上是以 數(shù)組的形式進(jìn)行存儲(chǔ)的
public class MyStackTest {public void test() {int i = 0;
{int b = 0;
b = i + 1;
}
int c = 0;
c = i + 1;
}
}
可以看到代碼塊中的變量 b 的起始PC為 4 結(jié)束長(zhǎng)度為 4 整個(gè)作用域的大小為 8
可以看到在本地變量表中,有四個(gè)局部變量,分別是內(nèi)部代碼塊中的 b , 非靜態(tài)方法局部變量 this 以及其他兩個(gè)定義變量 i 與 c ,但是 test 方法的局部變量的大槽數(shù)卻是 3 也就是說(shuō)給 test 方法所在棧幀中分配了 3 個(gè)局部變量的空間,這與本地局部變量表展現(xiàn)出來(lái)的結(jié)果出現(xiàn)了歧義。
那么為什么會(huì)出現(xiàn)這樣的問(wèn)題呢?
這是因?yàn)?內(nèi)部代碼塊中代碼作用域只是作用與代碼塊的內(nèi)部,只是在編譯期間起到作用,所以為了節(jié)省棧內(nèi)空間就未給棧幀中局部變量分配槽位。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧