5个版本

0.1.5 2020年5月14日
0.1.4 2020年5月13日
0.1.3 2020年5月13日
0.1.2 2020年5月13日
0.1.1 2020年5月11日

#377 in 内存管理

Apache-2.0/MIT

56KB
1.5K SLoC

FerrisGC

从头开始完全重新实现https://github.com/Manishearth/rust-gc,只提供兼容的接口

主要区别之一是线程安全的垃圾回收器实现以及线程局部垃圾回收器

以下是使用FerrisGC的简单示例

use ferris_gc::{Gc, Trace, Finalize, GcCell, ferris_gc_main, ApplicationCleanup, GcOpt};
use ferris_gc::sync::Gc as GlobalGc;
use ferris_gc::sync::GcCell as GlobalGcCell;
use core::time;
use std::thread;
use std::time::Duration;
use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::io::Write;

#[derive(Trace)]
struct MyStruct {
    jh: u32,
}

impl Drop for MyStruct {
    fn drop(&mut self) {
        println!("MyStruct in drop !!");
    }
}

impl Finalize for MyStruct {
    fn finalize(&self) {
        println!("MyStruct in finalize !!");
        let mut file = File::create("foo.txt");
        match file {
            Ok(mut f) => { f.write_all(b"Hello, world!") },
            Err(e) => { Err(e) },
        };
    }
}

struct MyStruct3 {
    jh: u32,
}

#[derive(Trace, Finalize)]
struct MyStruct39(#[unsafe_ignore_trace] MyStruct3, u16);

#[derive(Trace)]
struct MyStruct2 {
    jh: Gc<u32>,
}

#[derive(Trace, Finalize)]
struct MyStructStd {
    jh: GcOpt<u32>, // The same as Option<Gc<u32>>
    jh2: Box<&'static str>,
    jh3: Option<Box<&'static str>>,
    jh4: GcOpt<Box<&'static str>>, // The same as Option<Gc<Box<&'static str>>>
    jh5: Gc<Option<Box<&'static str>>>,
}

impl Drop for MyStruct2 {
    fn drop(&mut self) {
        println!("MyStruct in drop !!");
    }
}

impl Finalize for MyStruct2 {
    fn finalize(&self) {
        let mut file = File::create("foo2.txt");
        match file {
            Ok(mut f) => { f.write_all(b"Hello, world!") },
            Err(e) => { Err(e) },
        };
    }
}

#[ferris_gc_main]
fn main() {
    {
        let gc = Gc::new(2);
        let gc1 = Gc::new(MyStruct { jh: 3 });
        let gc2 = GcCell::new(MyStruct { jh: 3 });
        gc2.borrow_mut().jh = 2;
        let gc3 = Gc::new(MyStruct2 { jh: gc.clone() });
    }
    {
        let gc1 = Gc::new(MyStruct { jh: 3 });
        let gc2 = GlobalGc::new(MyStruct { jh: 3 });
        thread::spawn(move || {
            println!("gc2.jh is {}", gc2.jh);
        });
    }
    let gc3 = Gc::new(MyStruct { jh: 3 });
    let ten_secs = time::Duration::from_secs(5);
    thread::sleep(ten_secs);
    println!("Hello, GC World !!");
}

让我们一步步理解这里是什么

  1. #[derive(Trace, Finalize)]

    为特定对象实现Trace和Finalize的宏。这是必要的,因为Gc::newGcCell::new等待实现trait Trace的对象,使用该trait垃圾回收器能够收集不可达的对象...当对象被销毁时,会调用Finalize trait。您也可以为特定需求实现自定义的Finalize trait

  2. #[ferris_gc_main]

    您的程序中主函数的宏是必要的,用于在应用程序完成后销毁所有对象。这很有用,因为否则对象gc3不会被垃圾回收器销毁,并且不会调用finalization...

要添加依赖,应添加

[dependencies]
ferris-gc = { version = "0.1.5", features = ["proc-macro"] }

依赖项

~225KB