logo

Polyglot CheatSheet - Memory Management

Last Updated: 2023-03-01

Memory management, pointers and references.

C++

NO garbage collector.

// use stack
char a = 'a';
// no need to free a

// use heap
char *b = new char('b');
delete b;

Smart pointers:

// memory freed when ptr_a goes out of scope
unique_ptr<char> ptr_a(new char('a'));

// reference counted pointer
shared_ptr<char> ptr_b(new char('b'));

// pointer that does not increase reference counts
weak_ptr<char> ptr_c = ptr_b;

// memory freed when ptr_d goes out of scope
// differs from unique_ptr in copy semantics
auto_ptr<char> ptr_d(new char('d'));

Go

Go has two allocation primitives: new and make. Both are functions. Or use Composite Literals to create instances.

Composite Literals

To create a new instance:

// by field order.
f := File{fd, name, nil, 0}

// by field names; missing fiels will have zero values.
f := File{fd: fd, name: name}

new()

Unlike its namesakes in some other languages it does not initialize the memory, it only zeros it. new(T) returns a pointer (*T) to a newly allocated zero value of type T. (As Go doesn’t have constructors, the value will be initialised to T's zero value.)

The expressions new(Foo) and &Foo{} are equivalent.

make()

make() is used for slices, maps, or channels. make() allocates memory on the heap and initializes and puts zero or empty strings into values.

These three types represent references to data structures that must be initialized before use, e.g. for slice: a pointer to the underlying array, length, and capacity. ("initialized" means having meaning values, which may not be zero values.)

Unlike new(), make() returns the same type as its argument.

// make a map
a := make(map[int]string)

// make a slice
b := make([]string, 2, 10)

// make a channel
c := make(chan int, 1)
c <- 10
fmt.Println(<-c)

make() vs new()

make() is only used to create slices and maps and channels. The return of make() is initialized and ready to use. new() returns a pointer:

p := new(chan int)   // p has type: *chan int
c := make(chan int)  // c has type: chan int

For example:

  • v := make([]int, 10, 100): the slice v refers to a new array, with length 10 and capacity 100.
  • p := new([]int) returns a pointer to a newly allocated zeroed slice structure, *p == nil.

Rust

NO garbage collector.

// use stack
let a: char = 'a';

// use heap
let b = Box::new('b');

// b will be freed when it is out of scope
// or force free by mem::drop
mem::drop(b);

// reference counted pointer
let rc = Rc::new('c');

// atomically reference counted pointer
// can be safely used across threads
let arc = Arc::new('d');

Java

With garbage collection.

// use stack
char a = 'a';

// use heap
Character b = new Character('b');

// no way to free a or b, will be garbage collected

// reference that does not impact garbage collection
WeakReference<Character> weakRef = new WeakReference<>(ref);

// soft reference
SoftReference<Character> softRef = new SoftReference<>(ref);

All soft references to softly-reachable objects are guaranteed to be cleared before a JVM throws an OutOfMemoryError.