版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
在這里呢,我犯的錯誤其實有兩個。第一,我不應(yīng)該因為虛方法的性能效率,而放棄良好的設(shè)計。第二,通常來說,Jaa虛擬機中虛方法調(diào)用的性能開銷并不大,有些時候甚至可以完全消除。第一個錯誤是原則上的,這里就不展開了。至于第二個錯誤,我們今天便來聊一聊Jaa虛擬機中虛方法調(diào)用的具體實現(xiàn)。classPassengervoidpublicStringtoString(){...5classForeignerPassengerextendsPassengervoidpassThroughImmigration(){/*進外國人通道*/9classPassengerextendsPassengervoidpassThroughImmigration(){/*進通道*/voidvisitDutyShops(){/*逛*/14Passengerpassenger=這里我定義了一個抽象類,叫做Passenger,這個類中有一個名為passThroughImmigrationObjecttoString然后,我將Passenger地分為兩種 Passenger和ForeignerPassenger兩個類分別實現(xiàn)了passThroughImmigration這個方法,具體來說,就人走 Passenger這個類中,還特意添加了一個叫做 Shops的方法那么在實際運行過程中,JavaPassenger在上一篇中我曾經(jīng)提到,Java里所有非私有實例方法調(diào)用都會被編譯成invokevirtual指invokeinterfaceJava在絕大多數(shù)情況下,Jaa虛擬機需要根據(jù)調(diào)用者的動態(tài)類型,來確定虛方法調(diào)用的目標方法。這個過程我們稱之為動態(tài)綁定。那么,相對于靜態(tài)綁定的非虛方法調(diào)用來說,虛方法調(diào)用更加耗時。在Jaa虛擬機中,靜態(tài)綁定包括用于調(diào)用靜態(tài)方法的inoesaic指令,和用于調(diào)用構(gòu)造器、私有實例方法以及超類非私有實例方法的invoeseial指令。如果虛方法調(diào)用指向一個標記為final的方法,那么Jaa虛擬機也可以靜態(tài)綁定該虛方法調(diào)用的目標方法。JavaJavainvokevirtual使用的虛方法表(virtualmethodtable,vtable)為例介紹方法表的用法。invokeinterface所使用的接口方法表(interfacemethodtable,itable)稍微復(fù)雜些,這些方法可能是具體的、可執(zhí)行的方法,也可能是沒有相應(yīng)字節(jié)碼的抽象方法。方法表滿足兩個特質(zhì):其一,子類方法表中包含父類方法表中的所有方法;其二,子類方法在方法表中的索引值,與它所重寫的父類方法的索引值相同。我們知道,方法調(diào)用指令中的符號會在執(zhí)行之前解析成實際。對于靜態(tài)綁定的方法調(diào)用而言,實際將指向具體的目標方法。對于動態(tài)綁定的方法調(diào)用而言,實際則是方法表的索引值(實際上并不僅是索引值)。在執(zhí)行過程中,Java類的方法表包括兩個方法:它們分別對應(yīng)0號和1號。之所以方法表調(diào)換了toString方法和passThroughImmigrationtoStringObject中同名方法的索引值一致。為了保持簡潔,這里我就不考慮Object類中的其他方法。toString1passThroughImmigration ShopsPassengerpassenger=... 這里,Java虛擬機的工作可以想象為導(dǎo)航員。每當(dāng)來了一個乘客需要,導(dǎo)航員會先問人還是外國人(獲取動態(tài)類型),然后翻出/外國人對應(yīng)的小冊子(獲取動態(tài)類型的方法表),小冊子的第1頁便寫著應(yīng)該到哪條通道辦理(用1作為索引來實際上,使用了方法表的動態(tài)綁定與靜態(tài)綁定相比,僅僅多出幾個內(nèi)存解操作:棧上的調(diào)用者,調(diào)用者的動態(tài)類型,該類型的方法表,方法表中某個索引值所對應(yīng)的目標方法。相對于創(chuàng)建并初始化Jaa棧幀來說,這幾個內(nèi)存解操作的開銷簡直可以忽略不計。編譯代碼的情況中。這是因為即時編譯還擁有另外兩種性能更好的優(yōu)化:內(nèi)聯(lián)緩(inliningcache)和方法內(nèi)聯(lián)(methodinlining)內(nèi)聯(lián)緩存是一種加快動態(tài)綁定的優(yōu)化技術(shù)。它能夠緩存虛方法調(diào)用中調(diào)用者的動態(tài)類型,以及該類型所對應(yīng)的目標方法。在之后的執(zhí)行過程中,如果碰到已緩存的類型,內(nèi)聯(lián)緩存便會直接調(diào)用該類型所對應(yīng)的目標方法。如果沒有碰到已緩存的類型,內(nèi)聯(lián)緩存則會至使用基于方法表的動態(tài)綁定。在我們的例子中,這相當(dāng)于導(dǎo)航員記住了上一個乘客的國籍和對應(yīng)的通道,例如中國人,走了左邊通道。那么下一個乘客想要的時候,導(dǎo)航員會先問是不人,是的話就走左邊通道。如果不是的話,只好拿出外國人的小冊子,翻到第1頁,再告知查詢結(jié)果:右邊。多態(tài)(polymorhic)指的是有限數(shù)量種狀態(tài)的情況。二態(tài)(bimorphic)是多態(tài)的其中一種。對于內(nèi)聯(lián)緩存來說,我們也有對應(yīng)的單態(tài)內(nèi)聯(lián)緩存、多態(tài)內(nèi)聯(lián)緩存和超多態(tài)內(nèi)聯(lián)緩存。單態(tài)內(nèi)聯(lián)緩存,顧名思義,便是只緩存了一種動態(tài)類型以及它所對應(yīng)的目標方法。它的實現(xiàn)非常簡單:比較所緩存的動態(tài)類型,如果命中,則直接調(diào)用對應(yīng)的目標方法。態(tài)的,也就是只有一種動態(tài)類型。為了節(jié)省內(nèi)存空間,Java虛擬機只采用單態(tài)內(nèi)聯(lián)緩存。定。對于內(nèi)聯(lián)緩存中的內(nèi)容,我們有兩種選擇。一是替換單態(tài)內(nèi)聯(lián)緩存中的。這種做法就好比CPU中的數(shù)據(jù)緩存,它對數(shù)據(jù)的局部性有要求,即在替換內(nèi)聯(lián)緩存之后的一段時間內(nèi),方法調(diào)用的調(diào)用者的動態(tài)類型應(yīng)當(dāng)保持一致,從而能夠有效地利用內(nèi)聯(lián)緩存。因此,在情況下,我們用兩種不同類型的調(diào)用者,輪流執(zhí)行該方法調(diào)用,那么每次進行方法調(diào)用都將替換內(nèi)聯(lián)緩存。也就是說,只有寫緩存的額外開銷,而沒有用緩存的性能提升。另外一種選擇則是劣化為超多態(tài)狀態(tài)。這也是Jaa虛擬機的具體實現(xiàn)方式。處于這種狀態(tài)下的內(nèi)聯(lián)緩存,實際上放棄了優(yōu)化的機會。它將直接方法表,來動態(tài)綁定目標方法。與替換內(nèi)聯(lián)緩存的做法相比,它犧牲了優(yōu)化的機會,但是節(jié)省了寫緩存的額外開銷。具體到我們的例子,如果來了一隊乘客,其中外國人和依次隔開,那么在重復(fù)使用的單態(tài)內(nèi)聯(lián)緩存中,導(dǎo)航員需要反復(fù)記住上個的乘客,而且記住的信息在處理下一乘客時又會被替換掉。因此,倒不如一直不記,以此來節(jié)省腦細胞。雖然內(nèi)聯(lián)緩存附帶內(nèi)聯(lián)二字,但是它并沒有內(nèi)聯(lián)目標方法。這里需要明確的是,任何方法調(diào)用除非被內(nèi)聯(lián),否則都會有固定開銷。這些開銷來源于保存程序在該方法中的執(zhí)行位置,以及新建、壓入和彈出新方法所使用的棧幀。對于極其簡單的方法而言,比如說geter/seter,這部分固定開銷占據(jù)的CPU時間甚至超過了方法本身。此外,在即時編譯中,方法內(nèi)聯(lián)不僅僅能夠消除方法調(diào)用的固定開銷,而且還增加了進一步優(yōu)化的可能性,我們會在專欄的第二部分詳細介紹方法內(nèi)聯(lián)的內(nèi)容。今天我介紹了虛方法調(diào)用在Java虛方法調(diào)用包括invokevirtual指令和invokeinterface指令。如果這兩種指令所的目標方法被標記為final,那么Java虛擬機會采用靜態(tài)綁定。否則,JavaJava在解析虛方法調(diào)用時,Java虛擬機會下所的目標方法的索引值,并且在運行過程JavaJava否則,Java方法內(nèi)聯(lián)的影響,請使用如下令。//Runwith: mand='dontinline,*.passThroughImmigration' classPassengervoidpublicstaticvoidmain(String[]args)Passengera=new6Passengerb=new7longcurrent=8for(inti=1;i<=2_000_000_000;i++)9if(i%100_000_000==0)longtemp=System.out.println(temp-current=}Passengerc=(i<1_000_000_000)?a:}}18classPassengerextendsPassenger@OverridevoidpassThroughImmigration()21classForeignerPassengerextendsPassenger@OverridevoidpassThroughImmigration()24 歸科技所有 不得售賣。頁面已增加防盜追蹤,將依法其上一 04|JVM是如何執(zhí)行方法調(diào)用的?(上下一 06|JVM是如何處理異常的啊一大狗置 6 17 10就已經(jīng)確定了吧,比如A是B的子類,“BbnewBb=newA()”這種情況下b的動態(tài) 沒用過中文寫代碼,居然認為中文會編譯錯誤T﹏[root@localhostcqq]#javacPassenger.java[root@localhostcqq]#javaPassengercosttime: 7J5J5mand=dontinline,*.exitPassenger’這樣是錯的楊春 關(guān)于單態(tài)內(nèi)聯(lián)緩存中的記錄,hotspo緩存中的類型的話,直接通過基于方法表來找到具體的目標方法。那么內(nèi)聯(lián)緩存中的類型是永久不變,一直是第一次緩存的那個調(diào)用者類型嗎?吾是鋒 2鄭老師,您好。有個具體的問題想請教下,String類里面indexOf(Stringstr)調(diào)用的是自己類里面indexOf(Stringstr,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024材料供應(yīng)合同模板
- 2024年度咨詢服務(wù)合同標的:企業(yè)管理咨詢
- 2024年度城市軌道交通設(shè)備銷售合同
- 2024年度企業(yè)廣告發(fā)布合同具體條款
- 2024年品牌經(jīng)理合作協(xié)議
- 2024年雙層隔音門窗制作安裝合同
- 2024年城市供水供電設(shè)施建設(shè)與運營合同
- 2024年度垃圾清運服務(wù)合同
- 2024年度智能工廠設(shè)計與建造合同
- 2024年度八寶山殯儀館鮮花制品供應(yīng)商資質(zhì)審核與評估合同
- 湖北省武漢市漢陽區(qū)2023-2024學(xué)年九年級上學(xué)期期中考試英語試卷
- 智慧教育發(fā)展趨勢智慧課堂
- GB/T 43635-2024法庭科學(xué)DNA實驗室檢驗規(guī)范
- 勞動仲裁:如何處理仲裁證據(jù)
- 大酒店勞務(wù)派遣服務(wù)專項方案
- 醫(yī)院培訓(xùn)課件:《病室環(huán)境管理》
- 中國感染性休克指南
- 2021年初中部漢語聽寫大賽題庫
- 大數(shù)據(jù)治理與服務(wù)管理解決數(shù)據(jù)孤島問題的關(guān)鍵措施
- 帶電作業(yè)規(guī)程課件
- 建筑工程《擬投入本項目的主要施工設(shè)備表及試驗檢測儀器設(shè)備表》
評論
0/150
提交評論