2011-03-11 13:09:21 -07:00
|
|
|
// 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"
|
|
|
|
|
2012-10-30 14:38:01 -06:00
|
|
|
// Note: the MemStats struct should be kept in sync with
|
2012-10-21 11:08:13 -06:00
|
|
|
// struct MStats in malloc.h
|
|
|
|
|
2012-02-06 11:16:26 -07:00
|
|
|
// A MemStats records statistics about the memory allocator.
|
|
|
|
type MemStats struct {
|
2011-03-11 13:09:21 -07:00
|
|
|
// General statistics.
|
|
|
|
Alloc uint64 // bytes allocated and still in use
|
|
|
|
TotalAlloc uint64 // bytes allocated (even if freed)
|
runtime: account for all sys memory in MemStats
Currently lots of sys allocations are not accounted in any of XxxSys,
including GC bitmap, spans table, GC roots blocks, GC finalizer blocks,
iface table, netpoll descriptors and more. Up to ~20% can unaccounted.
This change introduces 2 new stats: GCSys and OtherSys for GC metadata
and all other misc allocations, respectively.
Also ensures that all XxxSys indeed sum up to Sys. All sys memory allocation
functions require the stat for accounting, so that it's impossible to miss something.
Also fix updating of mcache_sys/inuse, they were not updated after deallocation.
test/bench/garbage/parser before:
Sys 670064344
HeapSys 610271232
StackSys 65536
MSpanSys 14204928
MCacheSys 16384
BuckHashSys 1439992
after:
Sys 670064344
HeapSys 610271232
StackSys 65536
MSpanSys 14188544
MCacheSys 16384
BuckHashSys 3194304
GCSys 39198688
OtherSys 3129656
Fixes #5799.
R=rsc, dave, alex.brainman
CC=golang-dev
https://golang.org/cl/12946043
2013-09-06 14:55:40 -06:00
|
|
|
Sys uint64 // bytes obtained from system (sum of XxxSys below)
|
2011-03-11 13:09:21 -07:00
|
|
|
Lookups uint64 // number of pointer lookups
|
|
|
|
Mallocs uint64 // number of mallocs
|
|
|
|
Frees uint64 // number of frees
|
|
|
|
|
|
|
|
// Main allocation heap statistics.
|
2012-02-16 11:30:04 -07:00
|
|
|
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
|
2011-03-11 13:09:21 -07:00
|
|
|
|
|
|
|
// Low-level fixed-size structure allocator statistics.
|
|
|
|
// Inuse is bytes used now.
|
|
|
|
// Sys is bytes obtained from system.
|
undo CL 101570044 / 2c57aaea79c4
redo stack allocation. This is mostly the same as
the original CL with a few bug fixes.
1. add racemalloc() for stack allocations
2. fix poolalloc/poolfree to terminate free lists correctly.
3. adjust span ref count correctly.
4. don't use cache for sizes >= StackCacheSize.
Should fix bugs and memory leaks in original changelist.
««« original CL description
undo CL 104200047 / 318b04f28372
Breaks windows and race detector.
TBR=rsc
««« original CL description
runtime: stack allocator, separate from mallocgc
In order to move malloc to Go, we need to have a
separate stack allocator. If we run out of stack
during malloc, malloc will not be available
to allocate a new stack.
Stacks are the last remaining FlagNoGC objects in the
GC heap. Once they are out, we can get rid of the
distinction between the allocated/blockboundary bits.
(This will be in a separate change.)
Fixes #7468
Fixes #7424
LGTM=rsc, dvyukov
R=golang-codereviews, dvyukov, khr, dave, rsc
CC=golang-codereviews
https://golang.org/cl/104200047
»»»
TBR=rsc
CC=golang-codereviews
https://golang.org/cl/101570044
»»»
LGTM=dvyukov
R=dvyukov, dave, khr, alex.brainman
CC=golang-codereviews
https://golang.org/cl/112240044
2014-07-17 15:41:46 -06:00
|
|
|
StackInuse uint64 // bytes used by stack allocator
|
2011-03-11 13:09:21 -07:00
|
|
|
StackSys uint64
|
|
|
|
MSpanInuse uint64 // mspan structures
|
|
|
|
MSpanSys uint64
|
|
|
|
MCacheInuse uint64 // mcache structures
|
|
|
|
MCacheSys uint64
|
|
|
|
BuckHashSys uint64 // profiling bucket hash table
|
runtime: account for all sys memory in MemStats
Currently lots of sys allocations are not accounted in any of XxxSys,
including GC bitmap, spans table, GC roots blocks, GC finalizer blocks,
iface table, netpoll descriptors and more. Up to ~20% can unaccounted.
This change introduces 2 new stats: GCSys and OtherSys for GC metadata
and all other misc allocations, respectively.
Also ensures that all XxxSys indeed sum up to Sys. All sys memory allocation
functions require the stat for accounting, so that it's impossible to miss something.
Also fix updating of mcache_sys/inuse, they were not updated after deallocation.
test/bench/garbage/parser before:
Sys 670064344
HeapSys 610271232
StackSys 65536
MSpanSys 14204928
MCacheSys 16384
BuckHashSys 1439992
after:
Sys 670064344
HeapSys 610271232
StackSys 65536
MSpanSys 14188544
MCacheSys 16384
BuckHashSys 3194304
GCSys 39198688
OtherSys 3129656
Fixes #5799.
R=rsc, dave, alex.brainman
CC=golang-dev
https://golang.org/cl/12946043
2013-09-06 14:55:40 -06:00
|
|
|
GCSys uint64 // GC metadata
|
|
|
|
OtherSys uint64 // other system allocations
|
2011-03-11 13:09:21 -07:00
|
|
|
|
|
|
|
// Garbage collector statistics.
|
2014-09-24 12:18:25 -06:00
|
|
|
NextGC uint64 // next collection will happen when HeapAlloc ≥ this amount
|
|
|
|
LastGC uint64 // end time of last collection (nanoseconds since 1970)
|
2011-03-11 13:09:21 -07:00
|
|
|
PauseTotalNs uint64
|
2012-10-21 11:08:13 -06:00
|
|
|
PauseNs [256]uint64 // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256]
|
2011-03-11 13:09:21 -07:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-17 14:12:14 -06:00
|
|
|
var sizeof_C_MStats uintptr // filled in by malloc.goc
|
2011-03-11 13:09:21 -07:00
|
|
|
|
|
|
|
func init() {
|
2014-01-30 02:28:19 -07:00
|
|
|
var memStats MemStats
|
2012-02-06 11:16:26 -07:00
|
|
|
if sizeof_C_MStats != unsafe.Sizeof(memStats) {
|
|
|
|
println(sizeof_C_MStats, unsafe.Sizeof(memStats))
|
2014-09-17 12:49:32 -06:00
|
|
|
gothrow("MStats vs MemStatsType size mismatch")
|
2011-03-11 13:09:21 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-06 11:16:26 -07:00
|
|
|
// ReadMemStats populates m with memory allocator statistics.
|
2014-09-16 18:26:16 -06:00
|
|
|
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.gcing = 1
|
|
|
|
onM(stoptheworld)
|
|
|
|
|
|
|
|
gp.m.ptrarg[0] = noescape(unsafe.Pointer(m))
|
|
|
|
onM(readmemstats_m)
|
|
|
|
|
|
|
|
gp.m.gcing = 0
|
|
|
|
gp.m.locks++
|
|
|
|
semrelease(&worldsema)
|
|
|
|
onM(starttheworld)
|
|
|
|
gp.m.locks--
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation of runtime/debug.WriteHeapDump
|
|
|
|
func writeHeapDump(fd uintptr) {
|
|
|
|
semacquire(&worldsema, false)
|
|
|
|
gp := getg()
|
|
|
|
gp.m.gcing = 1
|
|
|
|
onM(stoptheworld)
|
|
|
|
|
|
|
|
gp.m.scalararg[0] = fd
|
|
|
|
onM(writeheapdump_m)
|
|
|
|
|
|
|
|
gp.m.gcing = 0
|
|
|
|
gp.m.locks++
|
|
|
|
semrelease(&worldsema)
|
|
|
|
onM(starttheworld)
|
|
|
|
gp.m.locks--
|
|
|
|
}
|