Heap & Resource Management
Monty uses a custom heap implementation for managing Python objects with reference counting and garbage collection. This page documents the key types and traits related to heap management.Heap
The heap is the central memory arena for allocating and managing heap-allocated Python values.Key Responsibilities
- Allocation: Allocates
HeapDataobjects and returnsHeapIdreferences - Reference Counting: Tracks reference counts for all heap objects
- Garbage Collection: Periodically reclaims unreachable objects
- Resource Tracking: Uses a
ResourceTrackerto enforce memory and allocation limits
Methods
allocate()
Allocates a new heap object and returns itsHeapId.
HeapData
required
The data to allocate on the heap
Returns the heap ID or a resource error if limits are exceeded
get()
Retrieves a reference to a heap object by itsHeapId.
HeapId
required
The heap ID of the object to retrieve
An immutable reference to the heap data
get_mut()
Retrieves a mutable reference to a heap object by itsHeapId.
HeapId
required
The heap ID of the object to retrieve
A mutable reference to the heap data
clone_with_heap()
Clones a value while properly incrementing reference counts for any heap-allocated components.&Value
required
The value to clone
The cloned value with incremented reference counts
drop_with_heap()
Drops a value while properly decrementing reference counts for any heap-allocated components. This is the correct way to drop aValue that may contain heap references.
Value
required
The value to drop (consumes ownership)
&mut Heap
required
Mutable reference to the heap for decrementing reference counts
HeapId
An opaque identifier for a heap-allocated object. Heap IDs are used to reference objects in the heap without directly holding pointers. This enables safe serialization, garbage collection, and reference counting.HeapData
The actual data stored in the heap. This is an enum containing all heap-allocated Python types:HeapData
Heap-allocated string
HeapData
Heap-allocated bytes object
HeapData
Heap-allocated list
HeapData
Heap-allocated tuple
HeapData
Heap-allocated dictionary
HeapData
Heap-allocated set
HeapData
Heap-allocated frozenset
HeapData
Heap-allocated arbitrary-precision integer
HeapData
Heap-allocated named tuple
HeapData
Heap-allocated dataclass instance
HeapData
Heap-allocated exception object
HeapData
Heap-allocated path object
HeapData
Heap-allocated cell (for closures)
HeapData
Heap-allocated closure
HeapData
Heap-allocated coroutine
HeapData
Heap-allocated range object
HeapData
Heap-allocated iterator
HeapData
Heap-allocated module
ResourceTracker
A trait for tracking and enforcing resource limits during execution.Methods
track_allocation()
Called before each heap allocation to check if limits allow the allocation.usize
required
The size of the allocation in bytes
Returns
Ok(()) if the allocation is allowed, or a ResourceError if limits are exceededcheck_time()
Called periodically to check if execution time limits have been exceeded.Returns
Ok(()) if execution should continue, or a ResourceError if time limits are exceededImplementations
NoLimitTracker
A no-op resource tracker that allows unlimited allocations and execution time.Custom Trackers
You can implement your ownResourceTracker to enforce custom limits:
PyTrait
The core trait implemented by all Python types (Value, HeapData).
Methods
py_type()
Returns the Python type of this value.The type enum variant (e.g.,
Type::Int, Type::Str)py_len()
Returns the length of this value if it’s a sequence or collection.The length, or
None if the type doesn’t support len()py_bool()
Returns the truthiness of this value according to Python’s truth testing rules.True if the value is truthy
py_repr()
Returns therepr() string for this value.
The repr string (may be owned or borrowed)
py_str()
Returns thestr() string for this value.
The str string (may be owned or borrowed)
Reference Counting Safety
All types that implementDropWithHeap hold heap references and must be cleaned up correctly on every code path. There are three mechanisms for ensuring this:
1. defer_drop! macro (preferred)
The simplest and safest approach. Use defer_drop! to bind a value into a guard that automatically drops it when scope exits.
defer_drop_mut! when you need a mutable reference:
2. HeapGuard (when you need control)
Use HeapGuard directly when you need to conditionally extract the value instead of dropping it.
