第七章運行時刻環(huán)境-計算機(jī)系主頁_第1頁
已閱讀1頁,還剩53頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、第七章 運行時刻環(huán)境,趙建華南京大學(xué)計算機(jī)系,運行時刻環(huán)境,運行時刻環(huán)境為數(shù)據(jù)分配安排存儲位置確定訪問變量時使用的機(jī)制過程之間的連接參數(shù)傳遞和操作系統(tǒng)、輸入輸出設(shè)備相關(guān)的其它接口主題存儲管理:棧分配、堆管理、垃圾回收對變量、數(shù)據(jù)的訪問,存儲分配的典型方式,目標(biāo)程序的代碼放置在代碼區(qū)靜態(tài)區(qū)、堆區(qū)、棧區(qū)分別放置不同類型生命期的數(shù)據(jù)值,靜態(tài)和動態(tài)存儲分配,靜態(tài)分配編譯器在編譯時刻就可以做出存儲分配決定,不需要考慮程序運行

2、時刻的情形全局變量動態(tài)分配棧式存儲:和過程的調(diào)用/返回同步進(jìn)行分配和回收,值的生命期和過程生命期相同堆存儲:數(shù)據(jù)對象比創(chuàng)建它的過程調(diào)用更長壽。手工進(jìn)行回收垃圾回收機(jī)制,棧式分配,內(nèi)容:活動樹活動記錄調(diào)用代碼序列棧中的變長數(shù)據(jù),活動樹,過程調(diào)用(過程活動)在時間上總是嵌套的:后調(diào)用的先返回因此用棧式分配來分配過程活動所需內(nèi)存空間。程序運行的所有過程活動可以用樹表示每個結(jié)點對應(yīng)于一個過程活動根結(jié)點對應(yīng)于main

3、過程的活動過程p的某次活動對應(yīng)的結(jié)點的所有子結(jié)點:此次活動所調(diào)用的各個過程活動(從左向右,表示調(diào)用的先后順序)。,活動樹的例子(1),程序:P277,圖7-2過程調(diào)用(返回)序列和活動樹的前序(后序)遍歷對應(yīng)假定當(dāng)前活動對應(yīng)結(jié)點N,那么所有尚未結(jié)束的活動對應(yīng)于N及其祖先結(jié)點。,活動記錄,過程調(diào)用和返回由控制棧進(jìn)行管理每個活躍的活動對應(yīng)于棧中的一個活動記錄活動記錄按照活動的開始時間,從棧底到棧頂排列,運行時刻棧的例子,a[11]

4、為全局變量main沒有局部變量r有局部變量iq的局部變量i,和參數(shù)m,n。,調(diào)用代碼序列,調(diào)用代碼序列(calling sequence)為活動記錄分配空間,填寫記錄中的信息;返回代碼序列(return sequence)恢復(fù)機(jī)器狀態(tài),使調(diào)用者繼續(xù)運行。調(diào)用代碼序列會分割到調(diào)用者和被調(diào)用者中。根據(jù)源語言、目標(biāo)機(jī)器、操作系統(tǒng)的限制,可以有不同的分割方案把代碼盡可能放在被調(diào)用者中。,調(diào)用/返回代碼序列的要求,數(shù)據(jù)方面能夠把參

5、數(shù)正確地傳遞給被調(diào)用者能夠把返回值傳遞給調(diào)用者控制方面能夠正確轉(zhuǎn)到被調(diào)用過程的代碼開始位置能夠正確轉(zhuǎn)回調(diào)用者的調(diào)用位置(的下一條指令)調(diào)用代碼序列和活動記錄的布局相關(guān),活動記錄的布局原則,調(diào)用者和被調(diào)用者之間傳遞的值放在被調(diào)用者活動記錄的開始位置固定長度的項放在中間位置控制鏈、訪問鏈、機(jī)器狀態(tài)字段早期不知道大小的項在活動記錄尾部棧頂指針(top_sp)通常指向固定長度字段的末端,調(diào)用代碼序列的例子,Calling se

6、quence調(diào)用者計算實在參數(shù)的值將返回地址和原top_sp存放到被調(diào)用者的活動記錄中。調(diào)用者增加top_sp的值(越過了局部數(shù)據(jù)、臨時變量、被調(diào)用者的參數(shù)、機(jī)器狀態(tài)字段)被調(diào)用者保存寄存器值和其他狀態(tài)字段被調(diào)用者初始化局部數(shù)據(jù)、開始運行。Return sequence被調(diào)用者將返回值放到和參數(shù)相鄰的位置恢復(fù)top_sp和寄存器,跳轉(zhuǎn)到返回地址。,調(diào)用者/被調(diào)用者的活動記錄,棧中的變長數(shù)據(jù),如果數(shù)據(jù)對象的生命期局限于過程活

7、動的生命期,就可以分配在運行時刻棧中。變長數(shù)組也可以放在棧中top指向?qū)嶋H的棧頂top_sp用于尋找頂層記錄的定長字段,非局部數(shù)據(jù)的訪問(無嵌套過程),沒有嵌套過程時的數(shù)據(jù)訪問C語言中,每個函數(shù)能夠訪問的變量函數(shù)的局部變量:相對地址已知,且存放在當(dāng)前活動記錄內(nèi),top_sp指針加上相對地址即可訪問全局變量:在靜態(tài)區(qū),地址在編譯時刻可知很容易將C語言的函數(shù)作為參數(shù)進(jìn)行傳遞參數(shù)中只需包括函數(shù)代碼的開始地址。在函數(shù)中訪問非局

8、部變量的模式很簡單,不需要考慮過程是如何激活的。,非局部數(shù)據(jù)的訪問(嵌套聲明過程),PASCAL中,如果過程A的聲明中包含了過程B的聲明,那么B可以使用在A中聲明的變量。當(dāng)B的代碼運行時,如果它使用的是A中的變量。那么這個變量指向運行棧中最上層的同名變量。但是,我們不能通過嵌套層次直接得到A的活動記錄的相對位置。必須通過訪問鏈訪問,void A(){intx,y;voidB(){int b;x = b+y;

9、}voidC(){B();} C(); B();},A的活動記錄,C的活動記錄,B的活動記錄,當(dāng)A調(diào)用C,C又調(diào)用B時:,當(dāng)A直接調(diào)用B時:,A的活動記錄,B的活動記錄,嵌套深度,嵌套深度是正文概念,可以根據(jù)源程序靜態(tài)地確定不內(nèi)嵌于任何其他過程中的過程,嵌套深度為1嵌套在深度為i的過程中的過程,深度為i+1.,深度為1sort深度為2readArray,exchange,quicksor

10、t深度為3partition,訪問鏈,訪問鏈被用于訪問非局部的數(shù)據(jù)如果過程p在聲明時嵌套在過程q的聲明中,那么p的活動記錄中的訪問鏈指向最上層的q的活動記錄。從棧頂活動記錄開始,訪問鏈形成了一個鏈路,嵌套深度沿著鏈路逐一遞減。設(shè)深度為np的過程p訪問變量x,而變量x在深度為nq的過程中聲明,那么np-nq在編譯時刻已知;從當(dāng)前活動記錄出發(fā),沿訪問鏈前進(jìn)np-nq次找到的活動記錄中的x就是要找的變量位置x相對于這個活動記

11、錄的偏移量在編譯時刻已知,訪問鏈的維護(hù)(直接調(diào)用過程),當(dāng)過程q調(diào)用過程p時,訪問鏈的變化p的深度大于q:根據(jù)作用域規(guī)則,p必然在q中直接定義;那么p的訪問鏈指向當(dāng)前活動記錄s調(diào)用q(1,9)遞歸調(diào)用:p=q。新活動記錄的訪問鏈等于當(dāng)前記錄的訪問鏈q(1,9)調(diào)用q(1,3))p的深度小于等于q的深度:此時必然有過程r,p直接在r中定義,而q嵌套在r中;p的訪問鏈指向棧最高的r的活動記錄。p調(diào)用exchange,訪問鏈的例子

12、,訪問鏈的維護(hù)(過程指針型參數(shù)),在傳遞過程指針參數(shù)時,過程型參數(shù)中不僅包含過程的代碼指針,還包括正確的訪問鏈。,顯示表,用訪問鏈訪問數(shù)據(jù)時,訪問開銷和嵌套深度差有關(guān)使用顯示表可以提高效率,訪問開銷為常量顯示表:數(shù)組d為每個嵌套深度保留一個指針指針d[i]指向棧中最高的、嵌套深度為i的活動記錄。如果程序p中訪問嵌套深度為i的過程q中聲明的變量x,那么d[i]直接指向相應(yīng)的(必然是q的)活動記錄注意:i在編譯時刻已知顯示表的維

13、護(hù)調(diào)用過程p時,在p的活動記錄中保存d[np]的值,并將d[np]設(shè)置為當(dāng)前活動記錄。從p返回時,恢復(fù)d[np]的值。,顯示表的例子,q(1,9)調(diào)用q(1,3)時,q的深度為2,q(1,3)調(diào)用p,p的深度為3,q調(diào)用e,e的深度為2,顯示表的用途,生成機(jī)器代碼時使用三地址代碼:x=y+z這里的x,y,z實際上是標(biāo)識符表項;假設(shè)x和y不是本地的局部數(shù)據(jù),標(biāo)識符表保存了x和y的嵌套深度和偏移量使用顯示表時LDR1*(

14、D+ny)LDR2Offy[R1]ADDR2Offz[sp]LDR1*(D+Nx)STOffx[R1]R2,堆管理,堆空間用于存放生命周期不確定、或生存到被明確刪除為止的數(shù)據(jù)對象例如:new生成的對象可以生存到被delete為止。malloc申請的空間生存到被free為止。存儲管理器分配/回收堆區(qū)空間的子系統(tǒng)根據(jù)語言而定C、C++需要手動回收空間Java可以自動回收空間(垃圾收集),存儲管理

15、器,基本功能分配:為每個內(nèi)存請求分配一段連續(xù)的、適當(dāng)大小的堆空間。首先從空閑的堆空間分配;如果不行則從操作系統(tǒng)中獲取內(nèi)存、增加堆空間?;厥眨喊驯换厥盏目臻g返回空閑空間緩沖池,以滿足其他內(nèi)存需求。評價存儲管理器的特性:空間效率:使程序需要的堆空間最小,即減小碎片程序效率:充分運用內(nèi)存系統(tǒng)的層次,提高效率低開銷:使分配/收回內(nèi)存的操作盡可能高效,堆空間的碎片問題,隨著程序分配/回收內(nèi)存,堆區(qū)逐漸被割裂成為若干空閑存儲塊(窗口

16、,hole)和已用存儲塊的交錯。分配一塊內(nèi)存時,通常是把一個窗口的一部分分配出去,其余部分成為更小的塊?;厥諘r,被釋放的存儲塊被放回緩沖池。通常要把連續(xù)的窗口接合成為更大的窗口。,,,,,,,碎片,已分配空間,堆空間分配方法,Best-Fit總是將請求的內(nèi)存分配在滿足請求的最小的窗口中。好處:可以將大的窗口保留下來,應(yīng)對更大的請求。First-Fit總是將對象放置在第一個能夠容納請求的窗口中。放置對象時花費時間較少,但是總

17、體性能較差。但是first-fit的分配方法通常具有較好的數(shù)據(jù)局部性。同一時間段內(nèi)的生成的對象經(jīng)常被分配在連續(xù)的空間內(nèi)。,使用容器的堆管理方法,設(shè)定不同大小的空閑塊規(guī)格,相同規(guī)格的塊放在同一容器中。較小的(較常用的)尺寸設(shè)置較多的容器。比如GNU的C編譯器將所有存儲塊對齊到8字節(jié)邊界??臻e塊的尺寸大?。?6,24,32,40,…,512大于512的按照對數(shù)劃分:每個容器的最小尺寸是前一個容器的最小尺寸的兩倍?;囊皦K:可以

18、擴(kuò)展的內(nèi)存塊分配方法:對于小尺寸的請求,直接在相應(yīng)容器中找。大尺寸的請求,在適當(dāng)?shù)娜萜髦袑ふ疫m當(dāng)?shù)目臻e塊??赡苄枰指顑?nèi)存塊??赡苄枰獜幕囊皦K中分割出更多的塊。,管理和接合空閑空間,當(dāng)回收一個塊時,可以把這個塊和相鄰的塊接合起來,構(gòu)成更大的塊。有些管理方法,比如說Lea,不需要進(jìn)行接合支持相鄰塊接合的數(shù)據(jù)結(jié)構(gòu)邊界標(biāo)記:在每一塊存儲塊的兩端,分別設(shè)置一個free/used位;相鄰的位置上存放字節(jié)總數(shù)。雙重鏈接的、嵌入式的

19、空閑塊列表:列表的指針存放在空閑塊中、用雙向指針的方式記錄了有哪些空閑塊。,例子,相鄰的存儲塊A、B、C當(dāng)回收B時,通過對free/used位的查詢,可以知道B左邊的A是空閑的,而C不空閑。同時還可以知道A、B合并為長度為300的塊。修改雙重鏈表,把A替換為A、B接合后的空閑塊注意:雙重鏈表中一個結(jié)點的前驅(qū)并不一定是它鄰近的塊,處理手工存儲管理,兩大問題:內(nèi)存泄露:未能刪除不可能再被引用的數(shù)據(jù)懸空指針引用:引用已被刪除的數(shù)據(jù)

20、其他問題空指針訪問/數(shù)組越界訪問解決方法:自動存儲管理正確的編程模式,正確的編程模式(1),對象所有者(Object ownership)每個對象總是有且只有一個所有者(指向此對象的指針);只有通過Owner才能夠刪除這個對象;當(dāng)Owner消亡時,這個對象要么也被刪除,要么已經(jīng)被傳遞給另一個owner。語句v=new ClassA;創(chuàng)建的對象的所有者為v;即將對v進(jìn)行賦值的時刻(v的值即將消亡)要么v已經(jīng)不是它所指對

21、象的所有者;比如g=v可以把v的ownership傳遞給g要么需要在返回/賦值之前,執(zhí)行delete v操作;編程時需要了解各個指針在不同時刻是否owner。防止內(nèi)存泄漏,避免多次刪除對象。不能解決懸空指針問題。,正確的編程模式(2),引用計數(shù)每個動態(tài)分配的對象附上一個計數(shù):記錄有多少個指針指向這個對象;在賦值/返回/參數(shù)傳遞時維護(hù)引用計數(shù)的一致性;在計數(shù)變成0之時刪除這個對象;可以解決懸空指針問題;但是在遞歸數(shù)據(jù)結(jié)構(gòu)中仍

22、然可能引起內(nèi)存泄漏;需要較大的運行時刻開銷?;趨^(qū)域的分配將一些生命期相同的對象分配在同一個區(qū)域中;整個區(qū)域同時刪除。,垃圾回收,垃圾:狹義:不能被引用(不可達(dá))的數(shù)據(jù)廣義:不需要再被引用的數(shù)據(jù)垃圾回收:自動回收不可達(dá)數(shù)據(jù)的機(jī)制,解除了程序員的負(fù)擔(dān)。使用的語言Java、Perl、ML、Modula-3、Prolog、Smalltalk,垃圾回收器的設(shè)計目標(biāo),基本要求:語言必須是類型安全的:保證回收器能夠知道數(shù)據(jù)元素是

23、否為一個指向某內(nèi)存塊的指針。類型不安全的語言:C,C++.性能目標(biāo)總體運行時間:不顯著增加應(yīng)用程序的總運行時間;空間使用:最大限度地利用可用內(nèi)存;停頓時間:當(dāng)垃圾回收機(jī)制啟動時,可能引起應(yīng)用程序的停頓。這個停頓應(yīng)該比較短;程序局部性:改善空間局部性和時間局部性。,可達(dá)性,直觀地講,可達(dá)性就是指一個存儲塊可以被程序訪問到。根集:不需要指針解引用就可以直接訪問的數(shù)據(jù)。Java:靜態(tài)成員、棧中變量;可達(dá)性根集的成員都是可達(dá)

24、的;對于任意一個對象,如果指向它的一個指針被保存在可達(dá)對象的某字段中、或數(shù)組元素中,那么這個對象也是可達(dá)的。性質(zhì):一旦一個對象變得不可達(dá),它就不會再變成可達(dá)的。,改變可達(dá)對象集合的操作,對象分配:返回一個指向新存儲塊的引用;參數(shù)傳遞/返回值:對象引用從實在參數(shù)傳遞到形式參數(shù),從返回值傳遞給調(diào)用者;引用賦值:u=v;v的引用被復(fù)制到u中,u中原來的引用丟失??赡苁沟胾原來指向的對象變得不可達(dá),并且遞歸地使得更多對象變得不可達(dá)。

25、過程返回:活動記錄出棧,局部變量消失,根集變?。豢赡苁沟靡恍ο笞兊貌豢蛇_(dá)。,垃圾回收方法分類,跟蹤相關(guān)操作,捕獲對象變得不可達(dá)的時刻,回收對象占用的空間在需要時,標(biāo)記出所有可達(dá)對象、回收其它對象,基于引用計數(shù)的垃圾回收器,每個對象有一個用于存放引用計數(shù)的字段,并按照如下方式維護(hù)對象分配:引用計數(shù)設(shè)為1參數(shù)傳遞:引用計數(shù)加1引用賦值:u=v:u指向的對象引用減1、v指向的對象引用加1過程返回:局部變量指向?qū)ο蟮囊糜嫈?shù)減1如

26、果一個對象的引用計數(shù)為0,在刪除對象之前,此對象中各個指針?biāo)笇ο蟮囊糜嫈?shù)減1回收器有缺陷,可能引起內(nèi)存泄漏開銷較大、但是不會引起停頓,引用計數(shù)的例子,考慮如下操作:y=xy是當(dāng)前函數(shù)f的局部變量,且f返回修改計數(shù)后總是先考慮是否釋放;釋放一個對象之前總是先處理對象內(nèi)部的指針,循環(huán)垃圾的例子,基于跟蹤的垃圾回收,標(biāo)記-清掃式垃圾回收標(biāo)記-清掃式垃圾回收的優(yōu)化標(biāo)記并壓縮垃圾回收拷貝垃圾回收,標(biāo)記-清掃式垃圾回收,一種直

27、接的、全面停頓的算法分成兩個階段標(biāo)記:從根集開始,跟蹤并標(biāo)記出所有可達(dá)對象;清掃:遍歷整個堆區(qū),釋放不可達(dá)對象;如果我們把數(shù)據(jù)對象看作頂點,引用看作有向邊,那么標(biāo)記的過程實際上是從根集開始的圖遍歷的過程。,標(biāo)記-清掃垃圾回收算法,例子,假設(shè)x是全局變量,y是當(dāng)前函數(shù)活動的局部變量;當(dāng)前活動返回之后,進(jìn)行標(biāo)記清掃A,D,E,F(xiàn),I,G,HB,C不可達(dá),基本抽象分類,每個存儲塊處于四種狀態(tài)之一空閑未被訪問待掃描已掃描

28、對存儲塊的操作會改變存儲塊的狀態(tài)應(yīng)用程序分配垃圾回收器訪問、掃描收回,標(biāo)記-清掃垃圾回收算法的優(yōu)化,基本算法需要掃描整個堆;優(yōu)化:用一個列表記錄所有已經(jīng)分配的對象;不可達(dá)對象等于已分配對象減去可達(dá)對象好處只需要掃描這個列表就可以完成清掃壞處需要維護(hù)這個列表,優(yōu)化后的算法,使用了四個列表:Scanned, Unscanned, Unreached, Free;,壓縮并標(biāo)記垃圾回收,對可達(dá)對象進(jìn)行重定位可以消除存儲碎片;

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論