Shredder: Garbage Collection as a Library for Rust

栏目: IT技术 · 发布时间: 3年前

内容简介:I'm excited to announceIn this example we hadThe only ergonomic issue to note is the need for guard objects. In

I'm excited to announce shredder , a library for Rust that provides a garbage collected smart pointer, Gc . This smart pointer is useful in the same sorts of situations as Rc , but can handle reference cycles. It's available on crates.io and Github . Here's how you could use it:

use std::cell::RefCell;

use shredder::{
    Gc, Scan,
    run_with_gc_cleanup,
    number_of_active_handles,
    number_of_tracked_allocations,
};

#[derive(Scan)]
struct Node {
    data: String,
    directed_edges: Vec<Gc<RefCell<Node>>>,
}

fn main() {
    // Using `run_with_gc_cleanup` is good practice
    // (it helps ensure destructors are run)
    run_with_gc_cleanup(|| {
        let a = Gc::new(RefCell::new(Node {
            data: "A".to_string(),
            directed_edges: Vec::new(),
        }));

        let b = Gc::new(RefCell::new(Node {
            data: "B".to_string(),
            directed_edges: Vec::new(),
        }));

        // Usually would need `get` for `Gc` data,
        // but `RefCell` is a special case
        a.borrow_mut().directed_edges.push(b.clone());
        b.borrow_mut().directed_edges.push(a);
        // We now have cyclical data!
    });
    // Everything was cleaned up!
    assert_eq!(number_of_tracked_allocations(), 0);
    assert_eq!(number_of_active_handles(), 0);
}

In this example we had #[derive(Scan)] on our struct. By implementing this trait, we let shredder know how it can find what Gc handles this data contains. This is an essential part of the tracing garbage collection that shredder implements. After we've done that, using the smart pointer is basically just plug and play!

The only ergonomic issue to note is the need for guard objects. In shredder , you always need a guard object when accessing data inside a Gc . Usually you need to use .get to get a GcGuard . (Guarded access is key to implementing shredder 's guarantees in a performant way.) Now, notice how we didn't have to do this in the above example. In general, Gc is only useful with interior mutability, so Gc<RefCell<?>> , Gc<Mutex<?>> and Gc<RwLock<?>> have special methods that let you skip this step (see documentation for more details).

People have experimented with garbage collection in Rust before, but I wasn't happy with existing libraries. I do not believe there is an existing Rust library providing an easy to use garbage collection solution that can robustly work in concurrent programs, as well as handle non- 'static data.   shredder does that and more. Let me break down what I consider the best features of shredder . (If you're interested in a deep dive into how it all works, I hope to provide a follow post on the design.)

1 Safety First)It should be impossible to cause unsafe behavior in safe code using shredder . The only unsafe parts of the API are writing manual implementations of the core traits: Scan , GcSafe and Finalize . I've done my best to ensure they have complete documentation explaining how to implement them safely.

2 Ergonomics Second)I believe a lot of the existing solutions are fairly hard to grok, requiring complex macros or weird setups with lifetimes. In shredder , Gc is basically just a fancy Arc , and I hope that makes the library easier to use. (And in the future I even want to make the guard object optional, assuming I can make it safe and performant!)

3 Ready for Fearless Concurrency) shredder was always designed to deal with multithreaded programs. You can send a Gc around just as if it was an Arc , and I think that's really cool! Keeping with this, I've designed the collector so that even if a thread holds onto a ton of GcGuard s, collection can still proceed as normal. The only operation that should implicitly block on collection in shredder is calling .get (or one of the helper methods wrapping .get ).

4 Seamless Destruction)By default, Gc::new only takes 'static data, and when it is found to be unreachable, it is dropped and its destructor is called. (There are safety checks in place to prevent you from exploiting cyclical data in the destructor.) This saves users the pain of having to deal with Finalize in the common case. The run_with_gc_cleanup method is also provided, and helps ensure destructors are run at the end of your program.

5 Clean Finalization)Sometimes, however, you need non- 'static data. Unfortunately, since we may scan data after lifetimes have expired, you cannot use raw references. Instead you must replace &'a T with R<'a, T> and &'a mut T with RMut<'a, T> . Outside of Scan and Finalize implementations, these can be used as if they were regular references. Speaking of Finalize , if you implement it, and use Gc::new_with_finalizer , then you can use unsafe code to define code to be run right before your data is deallocated.

6 Concurrent Collection and Destruction)Finally, as a nice side effect of shredder s design, automatic collection always happens in a background thread, and hopefully doesn't implement your regular processing too badly. Same goes for running destructors, which might actually be a performance win if your destructors are expensive.

shredder isn't perfect. It needs a lot more performance optimization, and I think the background collection can become even more concurrent in the future. It also has a non-trivial memory overhead. And of course it is very new and immature.

However, I think that's okay for now. I designed shredder to be another tool in the Rust programmer's toolbox. Gc is a very extreme escape hatch that lets you escape usual ownership rules. It's something that should be used carefully in small doses, where giving up the superior performance of RAII memory management is worth it. (Perhaps for user provided data with unpredictable loops, or interestingly shaped graphs.) I'm excited to see what people can do with it!

It's available on crates.io and Github . (If you've read this far, maybe you're interested in contributing? I've put some issues on the Github, and that might be a good place to start!)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Web Designer's Idea Book, Vol. 2

The Web Designer's Idea Book, Vol. 2

Patrick McNeil / How / 2010-9-19 / USD 30.00

Web Design Inspiration at a Glance Volume 2 of The Web Designer's Idea Book includes more than 650 new websites arranged thematically, so you can easily find inspiration for your work. Auth......一起来看看 《The Web Designer's Idea Book, Vol. 2》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具