1.png

rust has one of the best memory management.

  1. rust has a concept of ‘ownership’ and ‘borrow checker’.
  2. these prevent null pointer dereferencing, dangling pointers, and data races at compile time, without the need for a GC

For an example take this JAVA stack + heaptrace:

public class MainClass {
  public static void main(String[] args){
    int[] archie = new int[10]; // allocating some memory
    int[] archie2 = archie;
    // no need of freeing up the memory explicitly
  }
}

For this code pic #1 the variable 2 has a reference to the same data on the heap, so if the archie were to go out of scope we could just pop archie out of the stack and archie2 would still be referencing to the heap. when the GC comes, it can see that the state on the heap is still being used and it wouldn’t be deallocated. eventually when archie2 goes out of scope, gc will come and clean up the heap.

Screenshot 2024-12-16 at 10.57.22 PM.png

For Rust, when we come to L3, and when we run archie2=archie, this is called ‘move’ in rust that essentially means that the ownership of the resources is transferred. so when we move from archie to archie2, the data which was owned by archie is now owned by archie2 and since archie doesn’t own any data, it is uninitialized after L2 is executed, so L2 would be actually popped off of the stack.

Screenshot 2024-12-16 at 10.53.48 PM.png

Screenshot 2024-12-16 at 11.53.54 PM.png

Tools used:

Stack + Heap Trace(Rust): https://cel.cs.brown.edu/aquascope/

Stack + Heap Trace(Java): https://pythontutor.com/render.html#mode=display