mirror of
https://github.com/golang/go
synced 2024-11-19 10:44:47 -07:00
runtime: fix memstats
Newly allocated memory is subtracted from inuse, while it was never added to inuse. Span leftovers are subtracted from both inuse and idle, while they were never added. Fixes #8544. Fixes #8430. LGTM=khr, cookieo9 R=golang-codereviews, khr, cookieo9 CC=golang-codereviews, rlh, rsc https://golang.org/cl/130200044
This commit is contained in:
parent
2de65cad54
commit
30ef2c7deb
@ -283,6 +283,7 @@ struct MStats
|
||||
#define mstats runtime·memstats
|
||||
extern MStats mstats;
|
||||
void runtime·updatememstats(GCStats *stats);
|
||||
void runtime·ReadMemStats(MStats *stats);
|
||||
|
||||
// Size classes. Computed and initialized by InitSizes.
|
||||
//
|
||||
|
@ -16,10 +16,26 @@ func TestMemStats(t *testing.T) {
|
||||
// Test that MemStats has sane values.
|
||||
st := new(MemStats)
|
||||
ReadMemStats(st)
|
||||
if st.HeapSys == 0 || st.StackSys == 0 || st.MSpanSys == 0 || st.MCacheSys == 0 ||
|
||||
st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 {
|
||||
t.Fatalf("Zero sys value: %+v", *st)
|
||||
|
||||
// Everything except HeapReleased, because it indeed can be 0.
|
||||
if st.Alloc == 0 || st.TotalAlloc == 0 || st.Sys == 0 || st.Lookups == 0 ||
|
||||
st.Mallocs == 0 || st.Frees == 0 || st.HeapAlloc == 0 || st.HeapSys == 0 ||
|
||||
st.HeapIdle == 0 || st.HeapInuse == 0 || st.HeapObjects == 0 || st.StackInuse == 0 ||
|
||||
st.StackSys == 0 || st.MSpanInuse == 0 || st.MSpanSys == 0 || st.MCacheInuse == 0 ||
|
||||
st.MCacheSys == 0 || st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 ||
|
||||
st.NextGC == 0 || st.NumGC == 0 {
|
||||
t.Fatalf("Zero value: %+v", *st)
|
||||
}
|
||||
|
||||
if st.Alloc > 1e10 || st.TotalAlloc > 1e11 || st.Sys > 1e10 || st.Lookups > 1e10 ||
|
||||
st.Mallocs > 1e10 || st.Frees > 1e10 || st.HeapAlloc > 1e10 || st.HeapSys > 1e10 ||
|
||||
st.HeapIdle > 1e10 || st.HeapInuse > 1e10 || st.HeapObjects > 1e10 || st.StackInuse > 1e10 ||
|
||||
st.StackSys > 1e10 || st.MSpanInuse > 1e10 || st.MSpanSys > 1e10 || st.MCacheInuse > 1e10 ||
|
||||
st.MCacheSys > 1e10 || st.BuckHashSys > 1e10 || st.GCSys > 1e10 || st.OtherSys > 1e10 ||
|
||||
st.NextGC > 1e10 || st.NumGC > 1e9 {
|
||||
t.Fatalf("Insanely high value (overflow?): %+v", *st)
|
||||
}
|
||||
|
||||
if st.Sys != st.HeapSys+st.StackSys+st.MSpanSys+st.MCacheSys+
|
||||
st.BuckHashSys+st.GCSys+st.OtherSys {
|
||||
t.Fatalf("Bad sys value: %+v", *st)
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "malloc.h"
|
||||
|
||||
static MSpan *MHeap_AllocSpanLocked(MHeap*, uintptr);
|
||||
static void MHeap_FreeSpanLocked(MHeap*, MSpan*);
|
||||
static void MHeap_FreeSpanLocked(MHeap*, MSpan*, bool, bool);
|
||||
static bool MHeap_Grow(MHeap*, uintptr);
|
||||
static MSpan *MHeap_AllocLarge(MHeap*, uintptr);
|
||||
static MSpan *BestFit(MSpan*, uintptr, MSpan*);
|
||||
@ -326,7 +326,7 @@ HaveSpan:
|
||||
t->needzero = s->needzero;
|
||||
s->state = MSpanStack; // prevent coalescing with s
|
||||
t->state = MSpanStack;
|
||||
MHeap_FreeSpanLocked(h, t);
|
||||
MHeap_FreeSpanLocked(h, t, false, false);
|
||||
t->unusedsince = s->unusedsince; // preserve age (TODO: wrong: t is possibly merged and/or deallocated at this point)
|
||||
s->state = MSpanFree;
|
||||
}
|
||||
@ -413,7 +413,7 @@ MHeap_Grow(MHeap *h, uintptr npage)
|
||||
h->spans[p + s->npages - 1] = s;
|
||||
runtime·atomicstore(&s->sweepgen, h->sweepgen);
|
||||
s->state = MSpanInUse;
|
||||
MHeap_FreeSpanLocked(h, s);
|
||||
MHeap_FreeSpanLocked(h, s, false, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -467,7 +467,7 @@ mheap_free(MHeap *h, MSpan *s, int32 acct)
|
||||
mstats.heap_alloc -= s->npages<<PageShift;
|
||||
mstats.heap_objects--;
|
||||
}
|
||||
MHeap_FreeSpanLocked(h, s);
|
||||
MHeap_FreeSpanLocked(h, s, true, true);
|
||||
runtime·unlock(&h->lock);
|
||||
}
|
||||
|
||||
@ -506,12 +506,12 @@ runtime·MHeap_FreeStack(MHeap *h, MSpan *s)
|
||||
s->needzero = 1;
|
||||
runtime·lock(&h->lock);
|
||||
mstats.stacks_inuse -= s->npages<<PageShift;
|
||||
MHeap_FreeSpanLocked(h, s);
|
||||
MHeap_FreeSpanLocked(h, s, true, true);
|
||||
runtime·unlock(&h->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
MHeap_FreeSpanLocked(MHeap *h, MSpan *s)
|
||||
MHeap_FreeSpanLocked(MHeap *h, MSpan *s, bool acctinuse, bool acctidle)
|
||||
{
|
||||
MSpan *t;
|
||||
PageID p;
|
||||
@ -532,8 +532,10 @@ MHeap_FreeSpanLocked(MHeap *h, MSpan *s)
|
||||
runtime·throw("MHeap_FreeSpanLocked - invalid span state");
|
||||
break;
|
||||
}
|
||||
mstats.heap_inuse -= s->npages<<PageShift;
|
||||
mstats.heap_idle += s->npages<<PageShift;
|
||||
if(acctinuse)
|
||||
mstats.heap_inuse -= s->npages<<PageShift;
|
||||
if(acctidle)
|
||||
mstats.heap_idle += s->npages<<PageShift;
|
||||
s->state = MSpanFree;
|
||||
runtime·MSpanList_Remove(s);
|
||||
// Stamp newly unused spans. The scavenger will use that
|
||||
@ -606,6 +608,7 @@ scavenge(int32 k, uint64 now, uint64 limit)
|
||||
{
|
||||
uint32 i;
|
||||
uintptr sumreleased;
|
||||
MStats stats;
|
||||
MHeap *h;
|
||||
|
||||
h = &runtime·mheap;
|
||||
@ -615,11 +618,12 @@ scavenge(int32 k, uint64 now, uint64 limit)
|
||||
sumreleased += scavengelist(&h->freelarge, now, limit);
|
||||
|
||||
if(runtime·debug.gctrace > 0) {
|
||||
runtime·ReadMemStats(&stats);
|
||||
if(sumreleased > 0)
|
||||
runtime·printf("scvg%d: %D MB released\n", k, (uint64)sumreleased>>20);
|
||||
runtime·printf("scvg%d: inuse: %D, idle: %D, sys: %D, released: %D, consumed: %D (MB)\n",
|
||||
k, mstats.heap_inuse>>20, mstats.heap_idle>>20, mstats.heap_sys>>20,
|
||||
mstats.heap_released>>20, (mstats.heap_sys - mstats.heap_released)>>20);
|
||||
k, stats.heap_inuse>>20, stats.heap_idle>>20, stats.heap_sys>>20,
|
||||
stats.heap_released>>20, (stats.heap_sys - stats.heap_released)>>20);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user