2 个版本

0.1.2 2020 年 5 月 13 日
0.1.1 2020 年 5 月 11 日

43 in #回收器


ferris-gc 中使用

Apache-2.0/MIT

7KB
141

Buy Me A Coffee

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,垃圾回收器能够收集不可达的对象。当对象被销毁时,将调用 trait Finalize。您还可以为特定需求实现自定义 trait Finalize

  2. #[ferris_gc_main]

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

要添加依赖项,您应该添加

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

依赖项

~1.5MB
~35K SLoC