Skip to main content

Memory Management

Mux uses automatic reference counting (RC) for deterministic memory management without manual allocation or garbage collection.

Overview

Mux's memory model provides:

  • No manual free or delete - Memory cleaned up automatically
  • Deterministic cleanup - Objects freed when reference count reaches zero
  • No garbage collection pauses - Predictable performance
  • Heap allocation - Objects and collections live on the heap
  • Value semantics for primitives - Primitives passed by value

Memory Safety

No Null Pointers

Mux has no null pointers. Use optional<T> instead:

no_null_pointers.mux
Loading...

No Manual Memory Management

Cannot manually free memory or create dangling pointers:

no_manual_memory.mux
Loading...

No Use-After-Free

Reference counting prevents use-after-free:

no_use_after_free.mux
Loading...

Reference Counting Basics

Every heap-allocated value has a reference count that tracks how many references point to it:

reference_counting.mux
Loading...

Memory Layout

All heap-allocated values use a reference counting header. The RefHeader uses AtomicUsize for thread-safe atomic operations.

Automatic Cleanup

Scope-Based Cleanup

Variables are cleaned up when they go out of scope:

scope_cleanup.mux
Loading...

Early Returns

Cleanup happens even with early returns:

early_return_cleanup.mux
Loading...

Reference Count Operations

Increment (mux_rc_inc)

Reference count increases when:

  • Creating a new reference to existing value
  • Assigning to a new variable
  • Passing as a function argument
  • Adding to a collection
rc_increment.mux
Loading...

Decrement (mux_rc_dec)

Reference count decreases when:

  • Variable goes out of scope
  • Variable is reassigned
  • Function returns (cleanup of local variables)
rc_decrement.mux
Loading...

When mux_rc_dec returns true, the refcount reached zero and memory is freed automatically.

Collections and Reference Counting

Collections are RC-allocated and contain RC-allocated values:

collections_rc.mux
Loading...

Nested Collections

When a collection is freed, all contained values have their refcounts decremented:

nested_collections_rc.mux
Loading...

Objects and Reference Counting

Class instances use reference counting:

objects_rc.mux
Loading...

When all references are gone, the object is freed:

object_cleanup.mux
Loading...

Scope Tracking

The compiler generates cleanup code using a scope stack:

  1. Enter scope -> push_rc_scope() (function entry, if-block, loop-body, match-arm)
  2. Track variable -> track_rc_variable(name, alloca) for each RC-allocated variable
  3. Exit scope -> generate_all_scopes_cleanup() iterates through all scopes in reverse order

This ensures proper cleanup order and handles early returns.

Circular References

Warning: Mux's reference counting cannot automatically break circular references:

circular_reference.mux
Loading...

Solution: Avoid circular structures, or break cycles manually before scope exit.

Value vs Reference Semantics

Primitives (Value Semantics)

Primitives are passed by value (copied):

value_semantics.mux
Loading...

Objects (Reference Semantics)

Objects are passed by reference (shared):

reference_semantics.mux
Loading...

Collections (Reference Semantics)

Collections are passed by reference:

collections_reference.mux
Loading...

References

Mux supports explicit references for passing values by reference:

memory_refs.mux
Loading...

Reference Syntax:

  • Create reference: &variable or &expression
  • Dereference: *reference (required for both reading and writing)
  • Pass to functions: func(&int ref) declares parameter, update(&x) passes reference
  • References to references: Not supported

Design Note: Unlike some languages with automatic dereferencing, Mux requires explicit * for all reference operations. This makes memory access patterns explicit.

Performance Considerations

Atomic Operations

Reference counting uses atomic operations for thread safety:

  • Overhead: Atomic increment/decrement on each reference change
  • Cache: Reference count header may cause cache misses

Compared to Garbage Collection

Advantages:

  • Deterministic cleanup (no GC pauses)
  • Predictable performance
  • Lower memory overhead (no GC metadata)

Tradeoffs:

  • Cannot break circular references automatically
  • Atomic operations have cost
  • Must track references carefully

Compared to Manual Management

Advantages:

  • No manual free calls
  • No use-after-free bugs
  • No double-free bugs

Tradeoffs:

  • Cannot control exact deallocation time
  • Reference count overhead

See Also