From a87e5cdbf0c823cf8fd71f8c9636b802545174d3 Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Tue, 9 Aug 2022 14:03:19 -0700 Subject: [PATCH] runtime: add MemStats.TotalAlloc --- src/runtime/gc_conservative.go | 3 +++ src/runtime/gc_leaking.go | 4 ++++ src/runtime/mstats.go | 7 +++++++ src/runtime/mstats_conservative.go | 1 + src/runtime/mstats_leaking.go | 3 ++- 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/runtime/gc_conservative.go b/src/runtime/gc_conservative.go index 9d7a5584..bea46c9c 100644 --- a/src/runtime/gc_conservative.go +++ b/src/runtime/gc_conservative.go @@ -55,6 +55,7 @@ var ( metadataStart unsafe.Pointer // pointer to the start of the heap metadata nextAlloc gcBlock // the next block that should be tried by the allocator endBlock gcBlock // the block just past the end of the available space + gcTotalAlloc uint64 // for runtime.MemStats ) // zeroSizedAlloc is just a sentinel that gets returned when allocating 0 bytes. @@ -266,6 +267,8 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer { return unsafe.Pointer(&zeroSizedAlloc) } + gcTotalAlloc += uint64(size) + neededBlocks := (size + (bytesPerBlock - 1)) / bytesPerBlock // Continue looping until a run of free blocks has been found that fits the diff --git a/src/runtime/gc_leaking.go b/src/runtime/gc_leaking.go index 536ce256..e0a9ddc8 100644 --- a/src/runtime/gc_leaking.go +++ b/src/runtime/gc_leaking.go @@ -16,6 +16,9 @@ const gcAsserts = false // perform sanity checks // Ever-incrementing pointer: no memory is freed. var heapptr = heapStart +// Total amount allocated for runtime.MemStats +var gcTotalAlloc uint64 + // Inlining alloc() speeds things up slightly but bloats the executable by 50%, // see https://github.com/tinygo-org/tinygo/issues/2674. So don't. // @@ -26,6 +29,7 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer { // systems). size = align(size) addr := heapptr + gcTotalAlloc += uint64(size) heapptr += size for heapptr >= heapEnd { // Try to increase the heap and check again. diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go index 5f42d6a5..6a43c844 100644 --- a/src/runtime/mstats.go +++ b/src/runtime/mstats.go @@ -35,6 +35,13 @@ type MemStats struct { // HeapReleased is bytes of physical memory returned to the OS. HeapReleased uint64 + // TotalAlloc is cumulative bytes allocated for heap objects. + // + // TotalAlloc increases as heap objects are allocated, but + // unlike Alloc and HeapAlloc, it does not decrease when + // objects are freed. + TotalAlloc uint64 + // Off-heap memory statistics. // // The following statistics measure runtime-internal diff --git a/src/runtime/mstats_conservative.go b/src/runtime/mstats_conservative.go index a65c9da5..c7d12a07 100644 --- a/src/runtime/mstats_conservative.go +++ b/src/runtime/mstats_conservative.go @@ -21,5 +21,6 @@ func ReadMemStats(m *MemStats) { m.HeapReleased = 0 // always 0, we don't currently release memory back to the OS. m.HeapSys = m.HeapInuse + m.HeapIdle m.GCSys = uint64(heapEnd - uintptr(metadataStart)) + m.TotalAlloc = gcTotalAlloc m.Sys = uint64(heapEnd - heapStart) } diff --git a/src/runtime/mstats_leaking.go b/src/runtime/mstats_leaking.go index 70e0503e..b7834386 100644 --- a/src/runtime/mstats_leaking.go +++ b/src/runtime/mstats_leaking.go @@ -9,10 +9,11 @@ package runtime // call to ReadMemStats. This would not do GC implicitly for you. func ReadMemStats(m *MemStats) { m.HeapIdle = 0 - m.HeapInuse = uint64(heapptr - heapStart) + m.HeapInuse = gcTotalAlloc m.HeapReleased = 0 // always 0, we don't currently release memory back to the OS. m.HeapSys = m.HeapInuse + m.HeapIdle m.GCSys = 0 + m.TotalAlloc = gcTotalAlloc m.Sys = uint64(heapEnd - heapStart) }