Ruby 垃圾回收机制全解析
1. 垃圾回收基础问题与三色标记法
垃圾回收器在标记所有存活对象时,可能会遗漏新对象。一旦出现这种情况,回收器会回收该对象的内存,这可能导致应用程序丢失有效数据,或者在某个对象中添加垃圾数据。
为了解决这个问题,引入了三色标记法。该方法通过维护一个标记栈(mark stack)来实现,标记栈是一个待标记对象的列表。初始时,所有根对象都会被放入标记栈。垃圾回收器在标记对象时,会将对象从标记栈移到已标记对象列表中,同时将找到的子对象添加到标记栈。当标记栈为空时,垃圾回收器完成标记,此时剩余的对象被视为垃圾。
如果在标记过程中应用程序修改了某个对象,即使该对象之前已经被标记,回收器也会将其移回标记栈。这种改进后的标记算法就是三色标记法:已处理的对象为“黑色”,标记栈中的对象为“灰色”,其余对象为“白色”。
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(根对象):::process --> B(标记栈):::process
B --> C(已标记对象):::process
B --> D(子对象添加到标记栈):::process
E(修改对象):::process --> B
2. JVM 中的三种垃圾回收器
JVM 为了支持不同类型的应用程序和服务器硬件,提供了三种不同的垃圾回收器,可通过命令行参数在 JRuby 程序中选择使用:
-