# Memory and value semantics

> Understand managed allocation, value copies, references, GC reachability, and Alice safety boundaries.

Canonical: https://alice-lang.org/documentation/advanced/memory/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

## The runtime owns managed memory

Ordinary Alice programs run on .NET. Objects and arrays use managed memory, and the garbage collector reclaims unreachable objects. Alice does not require a manual `free`, and it does not currently implement Rust-style borrow checking or linear ownership.

References can alias the same mutable object. Copying a reference does not copy its contents. `val` prevents rebinding a variable; it does not freeze the object graph. See [.NET's GC fundamentals](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals) for the runtime model.

## Class references and struct values

| Type                      | Assignment behavior                | Main consequence                                               |
| ------------------------- | ---------------------------------- | -------------------------------------------------------------- |
| Class / record class      | Copy a reference                   | Callers can observe the same instance.                         |
| Struct / record struct    | Copy a value                       | Field values are copied; reference fields can still alias.     |
| Array / list / dictionary | Copy a reference                   | Mutation is visible through other aliases.                     |
| String                    | Copy a reference to immutable text | Transformations return text rather than modifying that string. |

A struct's fields can themselves reference arrays or objects. Copying that struct copies those references too. Choose value types for their semantics and measured data layout, not on the assumption that the word `struct` means every value is physically on the stack.

## Where allocations come from

A new object, array, string transformation, materialized collection, captured closure, boxed value, or library operation can allocate. Literal iterator chains ending in a supported sink may avoid intermediate storage, but a requested output collection still needs storage.

```alice
xs = [1.0, 2.0, 3.0, 4.0]
val scale = 2.0
puts xs.map { |x| x * scale }.select { |x| x > 4.0 }.sum
```

Expected output:

```text
14
```

[Edit and run in the Alice playground](https://playground.alice-lang.org/#code=u.eHMgPSBbMS4wLCAyLjAsIDMuMCwgNC4wXQp2YWwgc2NhbGUgPSAyLjAKcHV0cyB4cy5tYXAgeyB8eHwgeCAqIHNjYWxlIH0uc2VsZWN0IHsgfHh8IHggPiA0LjAgfS5zdW0)

This expression can fuse into one traversal. A version that stores each intermediate array has different storage needs. Inspect the emitted code and measure the actual workload before deciding what to optimize.

## Lifetimes and retention

An object stays live while a reachable owner retains it. Long-lived caches, static collections, event subscriptions, pending tasks, and closures are common places for references to remain longer than intended. Removing an item from one list does not make it collectible if another owner still references it.

Unsubscribe handlers when their subscription lifetime ends. Bound cache growth and queues. A garbage collector cannot infer that an application no longer wants reachable data.

## Stack-only values

`@[Stack]` emits a `ref struct`, which follows CLR restrictions on escape and storage. A `Span(T)` is a stack-only view over data; its backing data may still be an ordinary heap array or string. A view is not an owning allocation.

Use [buffer and span APIs](https://alice-lang.org/documentation/advanced/buffers.md) for a concrete example. Do not keep a span across an `await` or publish it into a heap object; use memory suitable for the asynchronous lifetime instead.

## Safety guarantees are separate

| Mechanism          | What it addresses                           | What it does not establish                  |
| ------------------ | ------------------------------------------- | ------------------------------------------- |
| Static types       | Invalid typed calls and operations          | Correct domain rules                        |
| Nullable checks    | Possible absent values in checked code      | Existence of an external resource           |
| `val`              | Binding reassignment                        | Deep immutability or exclusive access       |
| AL0202             | Recognized unsafe concurrent mutation       | All behavior of arbitrary foreign APIs      |
| Managed runtime    | Ordinary managed object lifetime and bounds | A sandbox for untrusted programs            |
| `using` / `ensure` | Deterministic cleanup code                  | Automatic transfer of application ownership |

Native interop and unsafe foreign libraries add different contracts. Proposed ownership designs in the repository are not shipped guarantees. Continue with [resource lifetimes](https://alice-lang.org/documentation/advanced/resources.md) and [allocation measurement](https://alice-lang.org/documentation/advanced/profiling.md).

## Continue reading

- Previous: [Build and distribute programs](https://alice-lang.org/documentation/guides/publishing.md)
- Next: [Resources and deterministic cleanup](https://alice-lang.org/documentation/advanced/resources.md)
