Ruby的GC機制原始碼分析(4)

2021-08-25 14:52:48 字數 1556 閱讀 8514

正如說過的那樣,ruby的gc是標記和清除型。具體來說,標記就是設定fl_mark標誌。搜尋已用的value,設定fl_mark,全部檢查過之後,再來看物件堆,釋放那些沒有設定fl_mark的物件。

rb_gc_mark()是乙個遞迴標記物件的函式。

rb_gc_mark()

首先,rany()定義如下。沒什麼特別的。

rany()

295  #define rany(o) ((rvalue*)(o))

(gc.c)

首先,檢查那些不是指標的東西和已經釋放的物件,以及對已標記物件的遞迴檢查。

obj->as.basic.flags |= fl_mark;

這樣obj(也就是函式的引數ptr)就被標記了。之後,順著從obj出來的引用進行標記。rb_gc_mark_children()就是這樣。

其它的,從check_stack()開始,主要是為了寫了些各種各樣防止棧溢位的**。rb_gc_mark()使用遞迴呼叫對物件進行標記,如果出現大的物件簇,機器棧的長度可能就會不足。在棧要溢位的時候,停止遞迴,將物件都放到全域性列表中,再重新開始標記。因為這部分**不是主線,省略過去。

下面是rb_gc_mark_children(),它只是將內部型別羅列出來,然後標記,冗長無趣。這裡省略了一些純粹是列舉的部分。

rb_gc_mark_children()

rb_gc_mark()是遞迴的呼叫,確認這點就可以了。省略的部分分別是nodet_***x的列舉。node的事會在第二部分介紹。

t_data(用於擴充套件程式庫的結構體)標記的部分需要確認一下。這段**是從第二個switch語句中提取出來的。

rb_gc_mark_children()-t_data

789        case t_data:

790 if (obj->as.data.dmark) (*obj->as.data.dmark)(data_ptr(obj));

791 break;

(gc.c)

這裡用的不是rb_gc_mark(),也不是與之類似的函式,而是來自使用者的函式dmark。其中當然應該用到rb_gc_mark(),不過,也可能不用。比如,乙個極端的情況,使用者定義的物件中不包含value就無需標記了。

Ruby的GC機制原始碼分析(2)

停止與複製 停止與複製型gc 是標記與清除型gc 的乙個變體。首先,準備多個物件域。為了簡化討論,假設只有兩個域 a 和b 將一邊標記為 active 生成的物件都放到active 域中 圖5 圖5 停止與複製 1 執行gc 時,按照標記與清除同樣的路徑進行搜尋。但是,與標記不同的是,物件本身移到了...

Ruby原始碼分析

struct rbasic struct robject struct rclass 以前研究過jvm,再看看動態語言原理都差不多。和jvm一樣,其中存著兩個必須的東西,變數表 iv tbl 和方法表 m tbl 這裡的變數表應該是只包含類變數 我不確定 super表示父類。其中為什麼要包含乙個變數...

Ruby原始碼分析(struct)

2012 01 08 hhuai struct rbasic struct robject struct rclass 以前研究過jvm,再看看動態語言原理都差不多。和jvm一樣,其中存著兩個必須的東西,變數表 iv tbl 和方法表 m tbl 這裡的變數表應該是只包含類變數 我不確定 super...