Skip to content

Q030. Can Rust ownership prevent resource and memory leaks?

Short Answer

No. Ownership prevents many invalid accesses and duplicate cleanups, but Rust's safety guarantees do not require every destructor to run. Safe code can intentionally leak with mem::forget or Box::leak, create Rc cycles, retain resources indefinitely, or terminate without unwinding. These leaks are memory-safe but can still exhaust memory, handles, locks, or other resources.

Deep Dive

Memory safety means that safe code does not use invalid memory, double-free an allocation, or violate reference rules. A leak leaves a resource reachable forever or abandons it without cleanup; that wastes resources but does not itself create an invalid access.

Common leak paths include:

  • mem::forget and ManuallyDrop;
  • Box::leak for intentional process-lifetime data;
  • strong-reference cycles built with Rc or Arc;
  • unbounded caches, queues, tasks, or registries;
  • process::exit, aborting panics, and external termination.

RAII gives reliable cleanup on ordinary scope exits and panic unwinding, but APIs and unsafe abstractions must remain sound even when callers prevent destruction.

Internal Model

The compiler enforces legal ownership transitions; it does not prove global liveness or eventual resource release. There is no tracing collector that discovers unreachable Rc cycles.

Leaked allocations normally remain reserved until process termination. The OS then reclaims process memory and handles, but application-level cleanup such as flushing, protocol shutdown, or transaction rollback may not occur.

Example

rust
use std::mem;

struct Trace(String);

impl Drop for Trace {
    fn drop(&mut self) {
        println!("drop {}", self.0);
    }
}

fn main() {
    let value = Trace(String::from("forgotten"));
    mem::forget(value);
}

Common Mistakes

  • Equating memory safety with guaranteed absence of leaks.
  • Assuming every leak requires unsafe code.
  • Treating process cleanup by the OS as equivalent to running application destructors.

Follow-ups

  • Why is mem::forget a safe function?
  • How does Weak<T> break reference-count cycles?
  • Which resources require cleanup beyond what process termination provides?

References

  • Rust Reference
  • Rust Standard Library
  • Rustonomicon