Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Rust have instead of a garbage collector?

Tags:

rust

People also ask

How does rust not have a garbage collector?

Rust does not use a garbage collector, but rather achieves these properties through a sophisticated, but complex, type system. Doing so makes Rust very efficient, but makes Rust relatively hard to learn and use. We designed Bronze, an optional, library-based garbage collector for Rust.

Does rust have automatic garbage collection?

And, to answer the initial question of the title, you do not have to manually take care of your garbage in Rust. This garbage collection is done by the runtime-system, but it is not called garbage collector anymore.

How does rust handle memory?

Rust doesn't have a defined memory model in the language specifications as of now and the memory structure is quite straightforward. Each Rust program process is allocated some virtual memory by the Operating System(OS), this is the total memory that the process has access to.

What is GC in Rust?

Gc. A garbage-collected pointer type over an immutable value. GcCell. A mutable memory location with dynamically checked borrow rules that can be used inside of a garbage-collected pointer.


Garbage collection is typically used periodically or on demand, like if the heap is close to full or above some threshold. It then looks for unused variables and frees their memory, depending on the algorithm.

Rust would know when the variable gets out of scope or its lifetime ends at compile time and thus insert the corresponding LLVM/assembly instructions to free the memory.

Rust also allows some kind of garbage collection, like atomic reference counting though.


The basic idea of managing resources (including memory) in a program, whatever the strategy, is that the resources tied to unreachable "objects" can be reclaimed. Beyond memory, those resources can be mutex locks, file handles, sockets, database connections...

Languages with a garbage collector periodically scan the memory (one way or another) to find unused objects, release the resources associated with them, and finally release the memory used by those objects.

Rust does not have a GC, how does it manage?

Rust has ownership. Using an affine type system, it tracks which variable is still holding onto an object and, when such a variable goes out of scope, calls its destructor. You can see the affine type system in effect pretty easily:

fn main() {
    let s: String = "Hello, World!".into();
    let t = s;
    println!("{}", s);
}

Yields:

<anon>:4:24: 4:25 error: use of moved value: `s` [E0382]
<anon>:4         println!("{}", s);

<anon>:3:13: 3:14 note: `s` moved here because it has type `collections::string::String`, which is moved by default
<anon>:3         let t = s;
                     ^

which perfectly illustrates that at any point in time, at the language level, the ownership is tracked.

This ownership works recursively: if you have a Vec<String> (i.e., a dynamic array of strings), then each String is owned by the Vec which itself is owned by a variable or another object, etc... thus, when a variable goes out of scope, it recursively frees up all resources it held, even indirectly. In the case of the Vec<String> this means:

  1. Releasing the memory buffer associated to each String
  2. Releasing the memory buffer associated to the Vec itself

Thus, thanks to the ownership tracking, the lifetime of ALL the program objects is strictly tied to one (or several) function variables, which will ultimately go out of scope (when the block they belong to ends).

Note: this is a bit optimistic, using reference counting (Rc or Arc) it is possible to form cycles of references and thus cause memory leaks, in which case the resources tied to the cycle might never be released.


With a language where you must manually manage memory, the distinction between the stack and the heap becomes critical. Every time you call a function, enough space is allocated on the stack for all variables contained within the scope of that function. When the function returns, the stack frame associated with that function is "popped" off the stack, and the memory is freed for future use.

From a practical standpoint, this inadvertent memory cleaning is used as a means of automatic memory storage that will be cleared at the end of the function's scope.

There is more information available here: https://doc.rust-lang.org/book/the-stack-and-the-heap.html