Memory management of vectors in Rust
Overview
Memory management is responsible for allocating segments of memory to programs at their request and then recovering it for reuse when it is not required anymore.
There are three main parts that make up a vector: its name, size, and capacity. The name is the identity of the vector. Whereas, the size and capacity are used to recognize the structure of the vector.
Size of the vector
The size of the vector tells us how many elements are currently available in the vector.
Syntax
<VectorName>.len();
Capacity of the vector
The capacity of the vector tells us how many elements a vector can hold.
Syntax
<VectorName>.capacity();
Note: The size of a vector is always less than or equal to the capacity of the vector.
Methodology
When a vector is created, its size and capacity are zero. When we perform operations like the push() function, the vector’s size increments by 1. With the pop() and remove() functions, the size of the vector decrements by 1.
Things are different when it comes to the capacity of the vector. When we use push() the data, the vector checks if its size is equal to its capacity. If they are equal, then the vector updates its capacity by a factor of 2. However, the capacity of the vector remains the same when we are using the pop() or the remove() function.
A vector occupies space even after popping or removing all of its elements since it is able to retain its capacity. This may cause memory shortages for future operations. Let’s see this in the following example.
Code example 1
fn main(){// Creating a vectorlet mut vect = Vec::new();// Pushing values 1-4 in vectorfor i in 0..5 {vect.push(i);println!("Pushing {}", i);}println!("Vector Capacity is {}", vect.capacity());println!("\n\n");// Removing values from vectorfor i in 0..5 {vect.remove(0);println!("Removing {}", i);}println!("Vector Capacity is {}", vect.capacity());}
The shrink_to_fit() method
Rust provides access to a built-in method called shrink_to_fit(). The shrink_to_fit() method ensures that the capacity of the vector always equals to the size of the vector.
Syntax
<VectorName>.shrink_to_fit();
Return value
The shrink_to_fit() method does not return any value(s).
Code example 2
fn main(){// Creating a vectorlet mut vect = Vec::new();// Pushing values 0-4 in vectorfor i in 0..5 {vect.push(i);println!("Pushing {}", i);}// Shrinking the capacity of vectorvect.shrink_to_fit();println!("Vector Capacity is {}", vect.capacity());println!("\n\n");// Removing values from vectorfor i in 0..5 {vect.remove(0);println!("Removing {}", i);}// Shrinking the capacity of vectorvect.shrink_to_fit();println!("Vector Capacity is {}", vect.capacity());}
It is best always to use the shrink_to_fit() method at the end of the program, because it deallocates all the memory cells of the capacity of that vector.
Free Resources