MRI垃圾回收机制全解析
1. 垃圾回收基础概念
在程序运行过程中,会不断创建新对象。当MRI(Matz’s Ruby Interpreter)把空闲列表里的对象都用完后,垃圾回收(GC)系统会暂停程序,找出不再使用的对象,回收它们占用的内存,以便分配给新对象。若没有找到未使用的对象,Ruby会向操作系统请求更多内存;若没有可用内存,Ruby会抛出内存不足异常并停止运行。
那些被程序分配但不再使用的对象被称为垃圾对象。为了识别这些垃圾对象,MRI会遍历对象C结构中的指针,从一个对象的引用找到另一个对象,以此找出所有活跃对象。
2. 标记过程
- 对象图 :程序中的根对象(如全局变量或Ruby内部确定应用程序必须使用的对象)是起点,通过引用关系连接其他对象,形成一个对象图。MRI在遍历对象图时,会标记找到的每个Ruby对象。在标记过程中,程序会暂停,以确保不会创建新的对象引用。
- 位图标记 :MRI使用位图标记技术来保存标记和未标记对象的信息。它将活跃对象的标记保存为一个名为空闲位图的数据结构中的一系列位。使用单独的内存结构来保存空闲位图,而不是将标记保存在对象附近,这与Unix的写时复制内存优化技术有关。写时复制允许Unix进程共享包含相同值的内存,通过单独保存标记位,MRI可以最大化进程间包含相同值的内存量。在Ruby 1.9及更早版本中,标记位保存在每个RVALUE结构内部,这使得垃圾回收器在标记活跃对象时几乎修改了Ruby的所有共享内存,使写时复制优化失效。
3. 清扫过程
标记完成后,