#garbage-collection #reference-counting #garbage #cycle #gc #rc #shared-ptr

jrsonnet-gcmodule

Cyclic garbage collection inspired by CPython's gc implementation

7 releases

0.3.9 Dec 2, 2024
0.3.8 Dec 2, 2024
0.3.7 May 28, 2024
0.3.6 Jul 27, 2023
0.3.4 Jun 5, 2022

#50 in Memory management

Download history 1012/week @ 2024-08-22 901/week @ 2024-08-29 899/week @ 2024-09-05 1138/week @ 2024-09-12 999/week @ 2024-09-19 1262/week @ 2024-09-26 793/week @ 2024-10-03 575/week @ 2024-10-10 461/week @ 2024-10-17 414/week @ 2024-10-24 366/week @ 2024-10-31 475/week @ 2024-11-07 569/week @ 2024-11-14 752/week @ 2024-11-21 758/week @ 2024-11-28 494/week @ 2024-12-05

2,739 downloads per month
Used in 12 crates (5 directly)

MIT license

120KB
2.5K SLoC

jrsonnet-gcmodule

Documentation crates.io Build Status

This is fork of https://github.com/quark-zju/gcmodule package, which implements several features for usage in jrsonnet

Garbage collection inspired by CPython's implementation.

This library provides a type Cc<T>. It provides shared reference-counting pointer, similar to stdlib Rc<T>. Unlike Rc, reference cycles in Cc can be collected.

If all values can be freed by just reference-counting, the collector used by this library does not take extra memory. This is different from some other implementations, which require manual collection to free the extra memory used by the collector.

Example

use gcmodule::{Cc, Trace};
use std::cell::RefCell;

type List = Cc<RefCell<Vec<Box<dyn Trace>>>>;
let a: List = Default::default();
let b: List = Default::default();
a.borrow_mut().push(Box::new(b.clone()));
b.borrow_mut().push(Box::new(a.clone())); // Form a cycle.
drop(a);
drop(b); // Internal values are not dropped due to the cycle.
gcmodule::collect_thread_cycles(); // Internal values are dropped.

For customized structures, they need to implement the Trace interface. That can be done by #[derive(Trace)].

use gcmodule::{Cc, Trace};
use std::cell::RefCell;

#[derive(Trace, Default)]
struct List(RefCell<Vec<Box<dyn Trace>>>);
{
    let a: List = Default::default();
    let b: List = Default::default();
    a.borrow_mut().push(Box::new(b.clone()));
    b.borrow_mut().push(Box::new(a.clone()));
}
assert_eq!(gcmodule::collect_thread_cycles(), 2); // 2 values are collected.

Refer to the documentation for more examples and technical details.

Similar Projects

bacon-rajan-cc v0.3

  • Both are reference counted, with cyclic garbage collection.
  • Both are mainly single-threaded, and stop-the-world.
  • Main APIs like Cc<T> and Trace are similar, or even compatible.
  • gcmodule is conceptually simpler. There is no need for the "colors" concept.
  • gcmodule provides ThreadedCc<T> for multi-thread environment.
  • bacon-rajan-cc requires manual collection to release GC metadata (but not the tracked object) even if the reference count logically drops to 0. See this commit message for some details.

rcgc v0.1

  • rcgc takes a novel approach - the collector holds strong references while everywhere else uses weak references.
  • Therefore, rcgc requires manual collection to release actual objects even if the reference count of objects (logically) drops to 0.

Dependencies

~0–4.5MB