众所周知,Ruby(MRI)中有三大神秘区域:
- GC
- GIL
- 编译/执行
我就是CRuby的GC,虽然大多数人不了解我,或者了解了也没什么卵用。但我还是得向你介绍一下我自己。我在这几年改变了很多。
我是谁
程序员在构建应用程序的时候,或多或少都需要使用内存,在C/C++中,绝大部分使用的内存都需要自己调用API去申请,用完了之后还要一点不剩地归还。这是一项繁琐且极易出bug的事,为了让程序员在这一过程中被解放出来,我及其众多兄弟就应运而生了。
在Ruby中,因为有我,你不用去管内存申请/释放这一过程。这样你可以更加专注于业务本身,节约时间去创造更多美妙的应用。
Ruby的内存空间
为了实现内存管理的目的,我需要做到两件事情:
- 当你需要内存对象时,我直接给你,用完后你不用管后续。(申请)
- 自动回收没有被使用的垃圾对象。(回收)
为了让你能更清晰地了解上面的过程,我需要简单介绍一下,我是如何管理内存的,这涉及到了Ruby的内存空间。
ObjectSpace
我会在Ruby堆空间中维护一个对象池,这个对象池也被称作ObjectSpace
, 你所使用的所有Ruby对象都是从这个池子中取出的,而我也会去清理池子中已经没有被使用的对象,达到循环利用的目的。
ObjectSpace
对象池是由很多堆页(page)构成的,每一个页的大小为16Kb。 每页中包含408个槽(slot)。 一个槽对应一个对象,你所使用的每一个对象都在对象池中占有一个槽。这些数据可以通过下面的方式得到:
GC::INTERNAL_CONSTANTS
=> {
:RVALUE_SIZE=>40, # 一个RVALUE结构体40个字节
:HEAP_PAGE_OBJ_LIMIT=>408,
# ...
}
RVALUE结构体
当然,槽只是一个形象化的抽象表述,你可能更加关心槽里面的对象究竟是如何被表达的,因为Ruby中有很多种不同的对象,如何表达它们呢? 答案是RVALUE
结构体, 每一个槽中躺的是一个RVALUE
结构体。
//有删减
typedef struct RVALUE {
union {
struct {
unsigned long flags;