Add maximum memory usage tracking to tracking allocator (#2772)

Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
m0tholith
2026-01-25 18:11:46 +03:00
committed by GitHub
parent cf03215564
commit 6cffb888ea
2 changed files with 17 additions and 1 deletions

View File

@@ -28,6 +28,8 @@ struct TrackingAllocator (Allocator)
AllocMap map;
usz mem_total;
usz allocs_total;
usz usage;
usz max_usage;
}
<*
@@ -70,6 +72,11 @@ fn usz TrackingAllocator.total_allocated(&self) => self.mem_total;
*>
fn usz TrackingAllocator.total_allocation_count(&self) => self.allocs_total;
<*
@return "the maximum amount of memory allocated"
*>
fn usz TrackingAllocator.max_allocated(&self) => self.max_usage;
fn Allocation[] TrackingAllocator.allocations_tlist(&self, Allocator allocator)
{
return self.map.tvalues();
@@ -88,27 +95,34 @@ fn void*? TrackingAllocator.acquire(&self, usz size, AllocInitType init_type, us
backtrace::capture_current(&bt);
self.map.set((uptr)data, { data, size, bt });
self.mem_total += size;
self.usage += size;
if (self.usage > self.max_usage) self.max_usage = self.usage;
return data;
}
fn void*? TrackingAllocator.resize(&self, void* old_pointer, usz size, usz alignment) @dynamic
{
void* data = self.inner_allocator.resize(old_pointer, size, alignment)!;
self.usage -= self.map[(uptr)old_pointer]!!.size;
self.map.remove((uptr)old_pointer);
void*[MAX_BACKTRACE] bt;
backtrace::capture_current(&bt);
self.map.set((uptr)data, { data, size, bt });
self.mem_total += size;
self.usage += size;
if (self.usage > self.max_usage) self.max_usage = self.usage;
self.allocs_total++;
return data;
}
fn void TrackingAllocator.release(&self, void* old_pointer, bool is_aligned) @dynamic
{
usz? old_size = self.map[(uptr)old_pointer].size;
if (catch self.map.remove((uptr)old_pointer))
{
unreachable("Attempt to release untracked pointer %p, this is likely a bug.", old_pointer);
}
self.usage -= old_size!!;
self.inner_allocator.release(old_pointer, is_aligned);
}
@@ -177,6 +191,7 @@ fn void? TrackingAllocator.fprint_report(&self, OutStream out) => @pool()
io::fprintfn(out, "- Total current allocations: %d", entries)!;
io::fprintfn(out, "- Total allocations (freed and retained): %d", self.allocs_total)!;
io::fprintfn(out, "- Total allocated memory (freed and retained): %d", self.mem_total)!;
io::fprintfn(out, "- Maximum memory usage: %d", self.max_usage)!;
if (leaks)
{
io::fprintn(out)!;

View File

@@ -23,7 +23,6 @@
- Make `foo.$abc` implicitly mean `foo.eval("$abc")`.
- Deprecating multi-level array length inference. `int[*][*]` is deprecated and will be removed 0.8.0.
- Combining argument-less initialization with argument init for bitstructs is now allowed e.g. `{ .b, .c = 123 }`.
- Bug when initializing an inferred array with deep structure using designated init #2826
### Fixes
- Regression with npot vector in struct triggering an assert #2219.
@@ -130,6 +129,7 @@
- Store of zero in lowering did not properly handle optionals in some cases #2837
- Bitstruct accidentally allowed other arrays than char arrays #2836
- Bitstruct as substruct fails to properly work with designated initializers. #2827
- Bug when initializing an inferred array with deep structure using designated init #2826
### Stdlib changes
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
@@ -158,6 +158,7 @@
- HashSet.len() now returns usz instead of int. #2740
- Add `mem::store` and `mem::load` which may combine both aligned and volatile operations.
- Deprecated `EMPTY_MACRO_SLOT` and its related uses, in favor of `optional_param = ...` named macro arguments. #2805
- Add tracking of peak memory usage in the tracking allocator.
## 0.7.8 Change list