120 likes | 291 Views
使用附標籤的函數及物件於保守性垃圾收集. Using Tagged Functions and Objects in Conservative Garbage Collection 吳培基 國立澎湖海事管理專科學校資訊工程科 澎湖縣 880 馬公市六合路 300 號 Email: pcwu@npit.edu.tw. 簡介 (1). 記憶體的使用可分成 : 靜態配置、堆疊 (stack) 配置及堆積 (heap) 配置。 動態記憶體管理有明示及自動二種方式 :
E N D
使用附標籤的函數及物件於保守性垃圾收集 Using Tagged Functions and Objects in Conservative Garbage Collection 吳培基國立澎湖海事管理專科學校資訊工程科澎湖縣880馬公市六合路300號Email: pcwu@npit.edu.tw
簡介 (1) • 記憶體的使用可分成:靜態配置、堆疊(stack)配置及堆積(heap)配置。 • 動態記憶體管理有明示及自動二種方式: • 明示: 程式中必須下達命令(如:free、delete、dispose等)來釋放動態配置的記憶空間。 • 物件導向程式語言等則由程式的執行時期環境自動回收無用的動態配置的記憶空間, 稱為垃圾收集。 • 垃圾收集: • 一個程式能操作的位置中有指標指向堆積資料的通稱為根(roots)。 • 從根出發所能存取到的即為使用中的空間; 沒有指標到達的區塊即為閒置的空間(稱為「垃圾」)。 • 垃圾收集器通常必須能找出記憶體內容中的指標。
簡介 (2) • C/C++等對指標與數值(scalar)的儲存空間並沒有嚴格限制:儲存指標的記憶空間也可用來存放數值。 • 保守性(conservative)垃圾收集方法: • 將所有記憶體字組(word)都視為一可能的指標。 • 適合於無法配合垃圾收集而改寫的程式; • 容易產生記憶空間的流失。 • 本文提出在函數(程序)及堆積物件上附加標籤, 以減少誤判指標的情形。
相關工作 (1) • Bartlett在記憶區塊附記提示: • 表示確定的指標及不確定的指標; • 確定的指標以拷貝垃圾收集(copying garbage collection)方法處理; 不確定的指標則採用保守性垃圾收集方法。 • Bohem「黑名單」方法: • 將目前無效(invalid)但將來可能誤認為有效物件位址的數值, 記錄在黑名單中, 在配置記憶空間時避開這些位址。 • Detlefs在每一堆積物件的表頭插入一物件描述器: • 位元圖(bitmap):每一位元1代表一字組含有指標; 位元0則表否。 • 整數陣列的位址:每一整數可表示一字組為數值(非指標)、確定的指標或不確定的指標, 並可表示重複的次數。
相關工作 (2) • Appel的方法: • 對每一程序附加一描述器表示型別資訊, • 垃圾收集時, 由堆疊的框架(stack frame)找出對應的程序及其描述器, 依此追蹤其他指標。 • Goldberg擴充Appel的方法: • 在每一程序呼叫指令後附加垃圾收集的程序的位址, • 垃圾收集時由活動記錄(activation record)中找到並執行這些程序。
函數及物件的附加標籤 (1) • 在函數或堆積物件附加標籤, 稱為gc標籤: • 代表該函數或堆積物件的記憶空間的下列狀況:a)全為數值; b)含0個數值; c)含n個數值; d)另有描述器說明(稱為gc描述器)。 • 函數的區域變數或堆積物件欄位的配置方式, 將資料依數值及非數值分成二個區塊, 該函數或堆積物件並採用前述c)型的gc標籤。 • 將gc標籤放置於動態記憶體管理所配置的記憶空間的表頭中的閒置位元。 • 根據函數的程式計數器或函數的活動記錄中的返回地址, 找出堆疊中每一活動記錄對應的函數的起始位址。 • 函數的gc標籤的表格, 表格的欄位包括:函數的起始位址、函數的gc標籤; 此一表格依函數位址排序。
函數及物件的附加標籤 (2) • 令bits為gc標籤編碼空間的位元數, gc標籤的編碼方式: • gc_tag = -1:全為數值。 • gc_tag = 0:含0個數值。 • gc_tag = n1 .. 2bits - 3:含n個數值。 • gc_tag = -2:另有描述器說明。 • 由於所需的位元數不多, 可將標籤塞在動態配置的記憶空間的表頭中的閒置位元。
與動態記憶體管理程式庫配合 (2) • gc標籤的使用可在配置堆積物件時, 當作參數傳入配置記憶體的函數: • void* malloc(size_t size, int gc_tag=0); • gc標籤的預設值為0, 表含0個數值, 即整個記憶區塊都可能存在有指標, 如此可與未提供適當gc標籤的程式相容。 • 使用舉例: • buffer = malloc(1024); // 預設為含0個數值 • buffer = malloc(1024, -1); // 全為數值
函數追溯 (1) • Appel的方法在每一函數附加一描述器表示型別資訊, 並藉由函數呼叫的返回地址追溯到函數的起始位址, 例如: • 0x100: call foo • 0x104: … • 0x1fc: tag_foo • 0x200: PROC foo … • 執行0x100(十六進位)位址的函數呼叫指令後, • 堆疊中將存入返回位址0x104。 • 進行垃圾收集時, 可從堆疊中的返回位址0x104及之前的指令「call foo」, 找到foo的位址0x200及之前的標籤tag_foo。
函數追溯 (2) • 上述方法無法用於間接呼叫(indirect calls)的情況。例如: • 0x0C0: PROC main … • 0x100: call r1 // r1 = &foo, foo的地址 • 0x104: … • 0x1fc: tag_foo • 0x200: PROC foo • 0x210: … • 從返回位址0x104只找到指令「call r1」, r1的值未知。 • 本文的方法, 藉由一排序過的函數的起始位址表: • 令開始垃圾收集時, 程式計數器為0x210, 由程式計數器0x210找出函數foo的位址為0x200; • 由返回位址0x104找出函數main的位址為0x0C0。
結論及未來工作 • 本文提出保守性垃圾收集方法中,在函數及堆積物件上附加標籤,以減少誤判指標的情形。 • 未來工作包括應用於物件導向程式語言如Java的垃圾收集。