// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package runtime import "unsafe" // Note: the MemStats struct should be kept in sync with // struct MStats in malloc.h // A MemStats records statistics about the memory allocator. type MemStats struct { // General statistics. Alloc uint64 // bytes allocated and still in use TotalAlloc uint64 // bytes allocated (even if freed) Sys uint64 // bytes obtained from system (sum of XxxSys below) Lookups uint64 // number of pointer lookups Mallocs uint64 // number of mallocs Frees uint64 // number of frees // Main allocation heap statistics. HeapAlloc uint64 // bytes allocated and still in use HeapSys uint64 // bytes obtained from system HeapIdle uint64 // bytes in idle spans HeapInuse uint64 // bytes in non-idle span HeapReleased uint64 // bytes released to the OS HeapObjects uint64 // total number of allocated objects // Low-level fixed-size structure allocator statistics. // Inuse is bytes used now. // Sys is bytes obtained from system. StackInuse uint64 // bytes used by stack allocator StackSys uint64 MSpanInuse uint64 // mspan structures MSpanSys uint64 MCacheInuse uint64 // mcache structures MCacheSys uint64 BuckHashSys uint64 // profiling bucket hash table GCSys uint64 // GC metadata OtherSys uint64 // other system allocations // Garbage collector statistics. NextGC uint64 // next collection will happen when HeapAlloc ≥ this amount LastGC uint64 // end time of last collection (nanoseconds since 1970) PauseTotalNs uint64 PauseNs [256]uint64 // circular buffer of recent GC pause durations, most recent at [(NumGC+255)%256] PauseEnd [256]uint64 // circular buffer of recent GC pause end times NumGC uint32 EnableGC bool DebugGC bool // Per-size allocation statistics. // 61 is NumSizeClasses in the C code. BySize [61]struct { Size uint32 Mallocs uint64 Frees uint64 } } // Size of the trailing by_size array differs between Go and C, // and all data after by_size is local to runtime, not exported. // NumSizeClasses was changed, but we can not change Go struct because of backward compatibility. // sizeof_C_MStats is what C thinks about size of Go struct. var sizeof_C_MStats = unsafe.Offsetof(memstats.by_size) + 61*unsafe.Sizeof(memstats.by_size[0]) func init() { var memStats MemStats if sizeof_C_MStats != unsafe.Sizeof(memStats) { println(sizeof_C_MStats, unsafe.Sizeof(memStats)) throw("MStats vs MemStatsType size mismatch") } } // ReadMemStats populates m with memory allocator statistics. func ReadMemStats(m *MemStats) { // Have to acquire worldsema to stop the world, // because stoptheworld can only be used by // one goroutine at a time, and there might be // a pending garbage collection already calling it. semacquire(&worldsema, false) gp := getg() gp.m.preemptoff = "read mem stats" systemstack(stoptheworld) systemstack(func() { readmemstats_m(m) }) gp.m.preemptoff = "" gp.m.locks++ semrelease(&worldsema) systemstack(starttheworld) gp.m.locks-- } //go:linkname runtime_debug_WriteHeapDump runtime/debug.WriteHeapDump func runtime_debug_WriteHeapDump(fd uintptr) { semacquire(&worldsema, false) gp := getg() gp.m.preemptoff = "write heap dump" systemstack(stoptheworld) systemstack(func() { writeheapdump_m(fd) }) gp.m.preemptoff = "" gp.m.locks++ semrelease(&worldsema) systemstack(starttheworld) gp.m.locks-- }