Skip to content

Commit c5bbdfb

Browse files
author
LoneWandererProductions
committed
Finalise the Readme
1 parent 90b4a7c commit c5bbdfb

1 file changed

Lines changed: 132 additions & 63 deletions

File tree

README.md

Lines changed: 132 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,163 @@
1-
# MemoryPrototype
1+
# ⚡ MemoryManager: High-Performance Unmanaged Arena Allocator for .NET
22

3-
**MemoryPrototype** is a high-performance, polymorphic unmanaged memory arena and handle framework built to bypass the .NET Garbage Collector for latency-critical runtime environments. Inspired by data-oriented, sharded architectures in modern low-latency game engines and production-grade runtimes, it implements stable handle indirection, generational version validation, zero-allocation custom structures, and drop-in memory lane strategies for both single-threaded and concurrent parallel execution profiles.
3+
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](License.txt)
4+
[![.NET 9.0+](https://img.shields.io/badge/.NET-8.0%2B-purple.svg)](https://dotnet.microsoft.com/)
5+
[![Build Status](https://img.shields.io/badge/Tests-Passing-brightgreen.svg)]()
46

5-
> ⚠️ **Engineering Status:** This is a polished **systems-engineering sandbox and architecture laboratory**. While fully verified by automated parallel chaos test suites to achieve exceptional throughput and zero GC allocation on hot paths, it is meant for specialized standalone subsystems. See the [Production Finish-Line Roadmap](#-the-production-finish-line-roadmap) for remaining considerations.
7+
**MemoryManager** is a low-level, production-grade memory arena architecture engineered for high-throughput, low-latency .NET applications such as game engine cores, real-time telemetry systems, database engines, and networking pipelines.
8+
9+
By managing native heap memory directly through platform allocators, **MemoryManager completely eliminates .NET Garbage Collector (GC) pressure**, guarantees CPU cache-line locality, and provides safe, generational handle tracking with in-place adaptive compaction.
610

711
---
812

9-
### 🚀 Key Features
13+
## 🏛️ System Architecture
14+
15+
The framework relies on a **Tiered Dual-Lane Memory Architecture** backed by an indirection handle tracking system.
16+
17+
```
18+
┌─────────────────────────────────────────┐
19+
│ MemoryArena / ConcurrentArena │
20+
└────────────────────┬────────────────────┘
21+
22+
┌─────────────────┴─────────────────┐
23+
▼ ▼
24+
┌─────────────────────┐ ┌─────────────────────┐
25+
│ FastLane │ │ SlowLane │
26+
│ (Hot / Short-Lived)│ │ (Cold / Long-Lived)│
27+
└──────────┬──────────┘ └──────────┬──────────┘
28+
│ │
29+
┌──────────────┼──────────────┐ ├─────────────────────┐
30+
▼ ▼ ▼ ▼ ▼
31+
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────────┐ ┌──────────────┐
32+
│ SlabLane │ │LinearLane │ │ FastLane │ │ BlobManager │ │ FreeList │
33+
│ (Slabs) │ │ (Bump) │ │(FreeList) │ │ (Size <=256B) │ │ (Size >256B) │
34+
└───────────┘ └───────────┘ └───────────┘ └───────────────┘ └──────────────┘
35+
```
36+
37+
### Key Architectural Pillars
38+
39+
* **Generational Handles (`MemoryHandle`):** Memory references are abstract versioned handles (`Id` + `Version`). Handles prevent Use-After-Free bugs and allow memory compaction without invalidating caller references.
40+
* **Pluggable Allocation Strategies:** Choose between **Slab Bins**, **Linear Bump**, or **Variable Free-Lists** depending on workload characteristics.
41+
* **Lock-Free Concurrency:** `ConcurrentMemoryArena` shards allocations across thread-local fast lanes with atomic cross-thread deallocation staging queues.
42+
* **In-Place Adaptive Compaction:** Compaction slides active memory blocks *in-place* using binary memory copies without doubling the RAM footprint or forcing full-heap defragmentation stalls.
1043

11-
1. **Stable Handle Indirection (Relocatable Memory)**
12-
Instead of handing out raw native pointers that permanently pin layout blocks in memory, the system yields opaque, lightweight $O(1)$ `MemoryHandle` tokens. This layer of indirection permits the background lanes to safely relocate data during defragmentation sweeps without ever breaking or invalidating external user references.
44+
---
1345

14-
2. **Generational Version Validation (Zombie Protection)**
15-
To completely eliminate the dangling pointer and double-free vulnerabilities common in unmanaged environments, each `MemoryHandle` carries an index `Id` and an atomic generation `Version`. When handles are recycled, their internal slots increment their generation counts. Legacy handles attempting to access stale memory addresses instantly trigger safe access exceptions instead of silently corrupting recycled data blocks.
46+
## ⚡ Key Features
1647

17-
3. **Sharded Thread Isolation (`ConcurrentMemoryArena`)**
18-
Achieves true scaling across high-core CPUs by providing an isolated, lock-free allocation path for every independent worker thread via `ThreadLocal<IFastLane>` storage. Workers allocate and recycle space at raw hardware speeds without fighting over a global execution lock. Cross-thread deallocations (Thread B freeing Thread A's memory) are offloaded asynchronously via atomic lock-free concurrent queues.
48+
* 🚀 **Zero GC Overhead:** Allocations reside entirely on the unmanaged heap (`Marshal.AllocHGlobal` / `NativeMemory`).
49+
* 🔒 **Zombie Handle Protection:** Version-stamped handles instantly detect and throw on access to deallocated memory blocks.
50+
* 🛡️ **Canary Guard Bands:** Debug builds feature pre- and post-guard band validation (`0xDEADBEEF`) to catch buffer underruns and overruns immediately.
51+
* 📦 **Zero-Allocation Collections:** Includes `ArenaList<T>`, `ArenaQueue<T>`, `ArenaBuffer<T>`, and `ArenaStack<T>` equipped with struct `Span<T>.Enumerator` support for zero-allocation `foreach` loops.
52+
* 🎯 **Policy-Based Maintenance:** Background Janitor maintenance automatically promotes aging or cold data out of fast lanes into the slow lane.
1953

20-
4. **Dynamic Segregated Size Classes (`AllocatorStrategy.Slab`)**
21-
Introduces an ultra-fast, zero-compaction fast-lane implementation. Slabs dynamically generate power-of-two size tracks (e.g., 16B, 32B, 64B... up to the configured boundary) matching your hardware layout. Memory allocation and deallocation within a slab are reduced to instantaneous $O(1)$ LIFO index array stack operations—completely eliminating external fragmentation.
54+
---
2255

23-
5. **The "Janitor" (Automated Tiered Eviction)**
24-
Data lifespans are managed policy-heuristically. Hot data lives in your choice of fast-lane architecture. If an allocation outstays its welcome (frame age limits), grows past entry thresholds, or is explicitly initialized via `AllocationHints.Cold`, the automated Janitor moves it downstream to a bulk `SlowLane` during maintenance frames, instantly deploying a seamless routing redirection stub in its wake.
56+
## 🚀 Getting Started
2557

26-
6. **Unified Polymorphic Framework (`IMemoryAllocator`)**
27-
Both `MemoryArena` (optimized for single-threaded isolated pipelines) and `ConcurrentMemoryArena` (built for massive multi-threaded scaling) implement the `IMemoryAllocator` interface contract. This allows all syntactic sugar, array helpers, type initializers, and string engines to be shared seamlessly across both execution environments.
58+
### 1. Basic Allocation & Typed Storage
2859

29-
---
60+
```csharp
61+
using MemoryManager.Core;
62+
using MemoryManager.Lanes;
63+
64+
// 1. Initialize configuration
65+
var config = new MemoryManagerConfig
66+
{
67+
FastLaneSize = 1024 * 1024, // 1 MB Hot Path
68+
SlowLaneSize = 4 * 1024 * 1024, // 4 MB Cold Path
69+
FastLaneStrategy = AllocatorStrategy.FreeList
70+
};
3071

31-
## 📐 Architecture Overview
72+
// 2. Instantiate Arena
73+
using var arena = new MemoryArena(config);
3274

33-
The system enforces a strict hierarchical topology over specialized unmanaged memory tiers.
75+
// 3. Store a struct directly in unmanaged memory
76+
var handle = arena.Store(new Vector3 { X = 10.0f, Y = 20.0f, Z = 30.0f });
3477

35-
* **⚡ FastLane**: Optimized for high-frequency, short-lived "hot" transient structures. Uses sequential **positive integers** (`1, 2, 3...`) for allocation IDs. Version tracking is backed by an ultra-fast, growable native pointer array (`uint*`) that maps handle IDs directly to generation counts via an $O(1)$ array offset calculation.
36-
* **🐌 SlowLane**: Optimized for large, persistent "cold" allocations or long-lived structural blocks. Uses sequential **negative integers** (`-1, -2, -3...`) for allocation IDs. Maps negative handles cleanly to positive array coordinates using an absolute value index converter (`-id`), retaining raw pointer lookup performance.
37-
* **🪐 BlobManager (Slow-Lane Sub-Allocator)**: Optimized for isolating tiny, chaotic allocations (e.g., $\le$ 256 bytes) away from the primary free block table to prevent memory fragmentation.
38-
* **走 OneWayLane (The Bridge)**: Orchestrates seamless data migration. It safely reads the original entry metadata to pull telemetry (preserving original frame age, priorities, and usage hints) and executes a vector-speed `System.Buffer.MemoryCopy` across the lane boundaries before converting the old site into a routing redirection stub.
39-
* **🧱 SlabLane (Segregated Bins)**: An alternative drop-in fast-lane strategy optimized for ultra-fast, uniform object pooling (e.g., ECS components, entities). It partitions unmanaged memory into distinct power-of-two size classes (16B, 32B, 64B, 128B, etc.). Both allocations and frees execute as instant $O(1)$ LIFO slot recycling operations, completely immunizing the hot path against external fragmentation and bypassing compaction stutters entirely.
40-
---
78+
// 4. Read back the struct
79+
var position = arena.Get<Vector3>(handle);
4180

42-
## 🧩 Config Presets & Advanced Usage
81+
// 5. Free memory when done
82+
arena.Free(handle);
83+
```
4384

44-
Configurations can be customized manually or generated via optimized static factories targeted at distinct architecture types:
85+
### 2. High-Performance Zero-GC `ArenaList<T>`
4586

4687
```csharp
47-
using MemoryManager;
48-
using MemoryManager.Core;
88+
using MemoryManager.Types;
89+
90+
// Create an unmanaged resizable list backed by the arena allocator
91+
using var list = new ArenaList<int>(arena, initialCapacity: 16);
4992

50-
// --- PROFILE 1: Ultra-Fast Real-Time Game Loop (Single Threaded Pipeline) ---
51-
// Employs a blazing fast O(1) Linear Bump allocator for transient per-frame arrays.
52-
var gameConfig = MemoryManagerConfig.CreateForGameLoop(totalBudget: 32 * 1024 * 1024);
53-
var physicsArena = new MemoryArena(gameConfig);
93+
list.Add(100);
94+
list.Add(200);
95+
list.Add(300);
5496

55-
// --- PROFILE 2: High-Velocity Concurrent Object Pooling (Multi-Threaded Scaling) ---
56-
// Provisions lock-free sharded Slab Lanes across all cores utilizing uniform size class bins.
57-
var poolConfig = MemoryManagerConfig.CreateForObjectPooling(totalBudget: 64 * 1024 * 1024);
58-
var parallelArena = new ConcurrentMemoryArena(poolConfig);
97+
// Fast, allocation-free iteration using Span<T>.Enumerator
98+
foreach (ref var value in list)
99+
{
100+
Console.WriteLine(value);
101+
}
102+
```
59103

60-
## Basic CRUD Operations & Extension Methods
104+
### 3. Circular Ring Buffer `ArenaQueue<T>`
61105

62106
```csharp
63-
using MemoryManager;
64-
using MemoryManager.Core;
107+
using MemoryManager.Types;
65108

66-
// Syntactic sugar extensions run seamlessly on any IMemoryAllocator instance
67-
IMemoryAllocator allocator = new ConcurrentMemoryArena(MemoryManagerConfig.CreateForObjectPooling());
109+
using var queue = new ArenaQueue<Point>(arena, initialCapacity: 32);
68110

69-
// 1. Structural Primitive Allocation & Direct Value Writing
70-
var healthHandle = allocator.Store(100);
111+
queue.Enqueue(new Point { X = 1, Y = 2 });
112+
queue.Enqueue(new Point { X = 3, Y = 4 });
71113

72-
// 2. High-Performance Fixed-Size Arrays
73-
var arrayHandle = allocator.AllocateArray<int>(count: 5);
74-
int[] sourceData = { 10, 20, 30, 40, 50 };
114+
var point = queue.Dequeue();
115+
```
75116

76-
// Executes atomic, size-validated bitwise memory copy
77-
allocator.BulkSet(arrayHandle, sourceData);
117+
---
78118

79-
// 3. Ultra-Fast Zero-Allocation Spans (Hot Path Loops)
80-
// Extract the span ONCE outside loops to execute modifications at raw hardware cache speed
81-
Span<int> activeSpan = allocator.GetSpan<int>(arrayHandle, sourceData.Length);
82-
for (int i = 0; i < activeSpan.Length; i++)
83-
{
84-
activeSpan[i] *= 2;
85-
}
119+
## 📐 Allocation Strategies Comparison
120+
121+
| Strategy | Allocation Time | Deallocation Time | Fragmentation | Best Use Case |
122+
| :--- | :---: | :---: | :---: | :--- |
123+
| **`Slab`** | $O(1)$ | $O(1)$ | Zero (Bin-local) | Fixed-size uniform struct pools |
124+
| **`LinearBump`** | $O(1)$ | $O(1)$ (Bulk) | N/A | High-speed per-frame scratch buffers |
125+
| **`FreeList`** | $O(N)$ Best/First-Fit | $O(1)$ Coalescing | Variable | Dynamic, unpredictable payload sizes |
126+
127+
---
128+
129+
## 🧹 Adaptive In-Place Compaction
130+
131+
The `SlowLane` provides two defragmentation policies via `CompactionStyle`:
132+
133+
```csharp
134+
// Full Compaction: Complete defragmentation (Ideal for loading boundaries)
135+
slowLane.Compact(CompactionStyle.Full);
136+
137+
// GoodEnough Compaction: Stops immediately once a gap of 4KB is opened (Ideal for frame-time budget preservation)
138+
slowLane.Compact(CompactionStyle.GoodEnough, requiredSize: 4096);
139+
```
140+
141+
* **In-Place Memory Sliding:** Compaction slides active memory blocks down using `System.Buffer.MemoryCopy` without allocating temporary secondary buffers.
142+
* **Automatic Healing:** If `Allocate()` fails due to fragmented space, `SlowLane` automatically triggers an in-place compaction pass before retrying.
143+
144+
---
145+
146+
## 🧪 Testing & Verification
147+
148+
The solution contains comprehensive unit, correctness, stress, and performance test suites covering:
149+
150+
* **Correctness:** Handle generation, stub redirection, and canary overrun/underrun validation.
151+
* **Compaction:** In-place data sliding, `GoodEnough` early termination, and `FreeMany` batch recovery.
152+
* **Stability:** Multi-threaded stress tests under concurrent alloc/free workloads.
153+
154+
To execute the full test suite:
155+
```bash
156+
dotnet test --configuration Release
157+
```
158+
159+
---
86160

87-
// 4. Symmetric Unmanaged UTF-8 String Storage (Bypasses GC Allocation 완전히)
88-
var stringHandle = allocator.StoreString("Hello from the native unmanaged Arena!");
89-
string decodedText = allocator.GetString(stringHandle);
161+
## 📜 License
90162

91-
// 5. Clean Resource Reclamation
92-
allocator.Free(healthHandle);
93-
allocator.Free(stringHandle);
94-
```
163+
This project is licensed under the Apache 2.0 License - see the [License.txt](License.txt) file for details.

0 commit comments

Comments
 (0)