mirror of
https://github.com/golang/go
synced 2024-11-21 21:24:45 -07:00
runtime: delete UpdateMemStats, replace with ReadMemStats(&stats).
Unexports runtime.MemStats and rename MemStatsType to MemStats. The new accessor requires passing a pointer to a user-allocated MemStats structure. Fixes #2572. R=bradfitz, rsc, bradfitz, gustavo CC=golang-dev, remy https://golang.org/cl/5616072
This commit is contained in:
parent
9c060b8d60
commit
842c906e2e
@ -1510,9 +1510,12 @@ func updateIndex() {
|
|||||||
log.Printf("index updated (%gs, %d bytes of source, %d files, %d lines, %d unique words, %d spots)",
|
log.Printf("index updated (%gs, %d bytes of source, %d files, %d lines, %d unique words, %d spots)",
|
||||||
secs, stats.Bytes, stats.Files, stats.Lines, stats.Words, stats.Spots)
|
secs, stats.Bytes, stats.Files, stats.Lines, stats.Words, stats.Spots)
|
||||||
}
|
}
|
||||||
log.Printf("before GC: bytes = %d footprint = %d", runtime.MemStats.HeapAlloc, runtime.MemStats.Sys)
|
memstats := new(runtime.MemStats)
|
||||||
|
runtime.ReadMemStats(memstats)
|
||||||
|
log.Printf("before GC: bytes = %d footprint = %d", memstats.HeapAlloc, memstats.Sys)
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
log.Printf("after GC: bytes = %d footprint = %d", runtime.MemStats.HeapAlloc, runtime.MemStats.Sys)
|
runtime.ReadMemStats(memstats)
|
||||||
|
log.Printf("after GC: bytes = %d footprint = %d", memstats.HeapAlloc, memstats.Sys)
|
||||||
}
|
}
|
||||||
|
|
||||||
func indexer() {
|
func indexer() {
|
||||||
|
@ -53,8 +53,9 @@ func TestCountEncodeMallocs(t *testing.T) {
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
enc := NewEncoder(&buf)
|
enc := NewEncoder(&buf)
|
||||||
bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
|
bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
|
||||||
runtime.UpdateMemStats()
|
memstats := new(runtime.MemStats)
|
||||||
mallocs := 0 - runtime.MemStats.Mallocs
|
runtime.ReadMemStats(memstats)
|
||||||
|
mallocs := 0 - memstats.Mallocs
|
||||||
const count = 1000
|
const count = 1000
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
err := enc.Encode(bench)
|
err := enc.Encode(bench)
|
||||||
@ -62,8 +63,8 @@ func TestCountEncodeMallocs(t *testing.T) {
|
|||||||
t.Fatal("encode:", err)
|
t.Fatal("encode:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
mallocs += runtime.MemStats.Mallocs
|
mallocs += memstats.Mallocs
|
||||||
fmt.Printf("mallocs per encode of type Bench: %d\n", mallocs/count)
|
fmt.Printf("mallocs per encode of type Bench: %d\n", mallocs/count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,8 +80,9 @@ func TestCountDecodeMallocs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dec := NewDecoder(&buf)
|
dec := NewDecoder(&buf)
|
||||||
runtime.UpdateMemStats()
|
memstats := new(runtime.MemStats)
|
||||||
mallocs := 0 - runtime.MemStats.Mallocs
|
runtime.ReadMemStats(memstats)
|
||||||
|
mallocs := 0 - memstats.Mallocs
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
*bench = Bench{}
|
*bench = Bench{}
|
||||||
err := dec.Decode(&bench)
|
err := dec.Decode(&bench)
|
||||||
@ -88,7 +90,7 @@ func TestCountDecodeMallocs(t *testing.T) {
|
|||||||
t.Fatal("decode:", err)
|
t.Fatal("decode:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
mallocs += runtime.MemStats.Mallocs
|
mallocs += memstats.Mallocs
|
||||||
fmt.Printf("mallocs per decode of type Bench: %d\n", mallocs/count)
|
fmt.Printf("mallocs per decode of type Bench: %d\n", mallocs/count)
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,9 @@ func cmdline() interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func memstats() interface{} {
|
func memstats() interface{} {
|
||||||
return runtime.MemStats
|
stats := new(runtime.MemStats)
|
||||||
|
runtime.ReadMemStats(stats)
|
||||||
|
return *stats
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -538,13 +538,14 @@ var _ bytes.Buffer
|
|||||||
func TestCountMallocs(t *testing.T) {
|
func TestCountMallocs(t *testing.T) {
|
||||||
for _, mt := range mallocTest {
|
for _, mt := range mallocTest {
|
||||||
const N = 100
|
const N = 100
|
||||||
runtime.UpdateMemStats()
|
memstats := new(runtime.MemStats)
|
||||||
mallocs := 0 - runtime.MemStats.Mallocs
|
runtime.ReadMemStats(memstats)
|
||||||
|
mallocs := 0 - memstats.Mallocs
|
||||||
for i := 0; i < N; i++ {
|
for i := 0; i < N; i++ {
|
||||||
mt.fn()
|
mt.fn()
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
mallocs += runtime.MemStats.Mallocs
|
mallocs += memstats.Mallocs
|
||||||
if mallocs/N > uint64(mt.count) {
|
if mallocs/N > uint64(mt.count) {
|
||||||
t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N)
|
t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N)
|
||||||
}
|
}
|
||||||
|
@ -442,8 +442,9 @@ func countMallocs(dial func() (*Client, error), t *testing.T) uint64 {
|
|||||||
}
|
}
|
||||||
args := &Args{7, 8}
|
args := &Args{7, 8}
|
||||||
reply := new(Reply)
|
reply := new(Reply)
|
||||||
runtime.UpdateMemStats()
|
memstats := new(runtime.MemStats)
|
||||||
mallocs := 0 - runtime.MemStats.Mallocs
|
runtime.ReadMemStats(memstats)
|
||||||
|
mallocs := 0 - memstats.Mallocs
|
||||||
const count = 100
|
const count = 100
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
err := client.Call("Arith.Add", args, reply)
|
err := client.Call("Arith.Add", args, reply)
|
||||||
@ -454,8 +455,8 @@ func countMallocs(dial func() (*Client, error), t *testing.T) uint64 {
|
|||||||
t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
|
t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
mallocs += runtime.MemStats.Mallocs
|
mallocs += memstats.Mallocs
|
||||||
return mallocs / count
|
return mallocs / count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1545,15 +1545,19 @@ func TestAddr(t *testing.T) {
|
|||||||
func noAlloc(t *testing.T, n int, f func(int)) {
|
func noAlloc(t *testing.T, n int, f func(int)) {
|
||||||
// once to prime everything
|
// once to prime everything
|
||||||
f(-1)
|
f(-1)
|
||||||
runtime.MemStats.Mallocs = 0
|
memstats := new(runtime.MemStats)
|
||||||
|
runtime.ReadMemStats(memstats)
|
||||||
|
oldmallocs := memstats.Mallocs
|
||||||
|
|
||||||
for j := 0; j < n; j++ {
|
for j := 0; j < n; j++ {
|
||||||
f(j)
|
f(j)
|
||||||
}
|
}
|
||||||
// A few allocs may happen in the testing package when GOMAXPROCS > 1, so don't
|
// A few allocs may happen in the testing package when GOMAXPROCS > 1, so don't
|
||||||
// require zero mallocs.
|
// require zero mallocs.
|
||||||
if runtime.MemStats.Mallocs > 5 {
|
runtime.ReadMemStats(memstats)
|
||||||
t.Fatalf("%d mallocs after %d iterations", runtime.MemStats.Mallocs, n)
|
mallocs := memstats.Mallocs - oldmallocs
|
||||||
|
if mallocs > 5 {
|
||||||
|
t.Fatalf("%d mallocs after %d iterations", mallocs, n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,20 +10,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestGcSys(t *testing.T) {
|
func TestGcSys(t *testing.T) {
|
||||||
|
memstats := new(runtime.MemStats)
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
sys := runtime.MemStats.Sys
|
sys := memstats.Sys
|
||||||
|
|
||||||
for i := 0; i < 1000000; i++ {
|
for i := 0; i < 1000000; i++ {
|
||||||
workthegc()
|
workthegc()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should only be using a few MB.
|
// Should only be using a few MB.
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
if sys > runtime.MemStats.Sys {
|
if sys > memstats.Sys {
|
||||||
sys = 0
|
sys = 0
|
||||||
} else {
|
} else {
|
||||||
sys = runtime.MemStats.Sys - sys
|
sys = memstats.Sys - sys
|
||||||
}
|
}
|
||||||
t.Logf("used %d extra bytes", sys)
|
t.Logf("used %d extra bytes", sys)
|
||||||
if sys > 4<<20 {
|
if sys > 4<<20 {
|
||||||
|
@ -234,7 +234,7 @@ struct MStats
|
|||||||
} by_size[NumSizeClasses];
|
} by_size[NumSizeClasses];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define mstats runtime·MemStats /* name shared with Go */
|
#define mstats runtime·memStats /* name shared with Go */
|
||||||
extern MStats mstats;
|
extern MStats mstats;
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@ package runtime
|
|||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
type MemStatsType struct {
|
// A MemStats records statistics about the memory allocator.
|
||||||
|
type MemStats struct {
|
||||||
// General statistics.
|
// General statistics.
|
||||||
// Not locked during update; approximate.
|
|
||||||
Alloc uint64 // bytes allocated and still in use
|
Alloc uint64 // bytes allocated and still in use
|
||||||
TotalAlloc uint64 // bytes allocated (even if freed)
|
TotalAlloc uint64 // bytes allocated (even if freed)
|
||||||
Sys uint64 // bytes obtained from system (should be sum of XxxSys below)
|
Sys uint64 // bytes obtained from system (should be sum of XxxSys below)
|
||||||
@ -43,7 +43,6 @@ type MemStatsType struct {
|
|||||||
DebugGC bool
|
DebugGC bool
|
||||||
|
|
||||||
// Per-size allocation statistics.
|
// Per-size allocation statistics.
|
||||||
// Not locked during update; approximate.
|
|
||||||
// 61 is NumSizeClasses in the C code.
|
// 61 is NumSizeClasses in the C code.
|
||||||
BySize [61]struct {
|
BySize [61]struct {
|
||||||
Size uint32
|
Size uint32
|
||||||
@ -54,21 +53,17 @@ type MemStatsType struct {
|
|||||||
|
|
||||||
var sizeof_C_MStats uintptr // filled in by malloc.goc
|
var sizeof_C_MStats uintptr // filled in by malloc.goc
|
||||||
|
|
||||||
|
var memStats MemStats
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if sizeof_C_MStats != unsafe.Sizeof(MemStats) {
|
if sizeof_C_MStats != unsafe.Sizeof(memStats) {
|
||||||
println(sizeof_C_MStats, unsafe.Sizeof(MemStats))
|
println(sizeof_C_MStats, unsafe.Sizeof(memStats))
|
||||||
panic("MStats vs MemStatsType size mismatch")
|
panic("MStats vs MemStatsType size mismatch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemStats holds statistics about the memory system.
|
// ReadMemStats populates m with memory allocator statistics.
|
||||||
// The statistics may be out of date, as the information is
|
func ReadMemStats(m *MemStats)
|
||||||
// updated lazily from per-thread caches.
|
|
||||||
// Use UpdateMemStats to bring the statistics up to date.
|
|
||||||
var MemStats MemStatsType
|
|
||||||
|
|
||||||
// UpdateMemStats brings MemStats up to date.
|
|
||||||
func UpdateMemStats()
|
|
||||||
|
|
||||||
// GC runs a garbage collection.
|
// GC runs a garbage collection.
|
||||||
func GC()
|
func GC()
|
||||||
|
@ -997,7 +997,7 @@ runtime·gc(int32 force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
runtime·UpdateMemStats(void)
|
runtime·ReadMemStats(MStats *stats)
|
||||||
{
|
{
|
||||||
// Have to acquire gcsema to stop the world,
|
// Have to acquire gcsema to stop the world,
|
||||||
// because stoptheworld can only be used by
|
// because stoptheworld can only be used by
|
||||||
@ -1007,6 +1007,7 @@ runtime·UpdateMemStats(void)
|
|||||||
m->gcing = 1;
|
m->gcing = 1;
|
||||||
runtime·stoptheworld();
|
runtime·stoptheworld();
|
||||||
cachestats();
|
cachestats();
|
||||||
|
*stats = mstats;
|
||||||
m->gcing = 0;
|
m->gcing = 0;
|
||||||
runtime·semrelease(&gcsema);
|
runtime·semrelease(&gcsema);
|
||||||
runtime·starttheworld(false);
|
runtime·starttheworld(false);
|
||||||
|
@ -75,7 +75,8 @@ func WriteHeapProfile(w io.Writer) error {
|
|||||||
|
|
||||||
// Print memstats information too.
|
// Print memstats information too.
|
||||||
// Pprof will ignore, but useful for people.
|
// Pprof will ignore, but useful for people.
|
||||||
s := &runtime.MemStats
|
s := new(runtime.MemStats)
|
||||||
|
runtime.ReadMemStats(s)
|
||||||
fmt.Fprintf(b, "\n# runtime.MemStats\n")
|
fmt.Fprintf(b, "\n# runtime.MemStats\n")
|
||||||
fmt.Fprintf(b, "# Alloc = %d\n", s.Alloc)
|
fmt.Fprintf(b, "# Alloc = %d\n", s.Alloc)
|
||||||
fmt.Fprintf(b, "# TotalAlloc = %d\n", s.TotalAlloc)
|
fmt.Fprintf(b, "# TotalAlloc = %d\n", s.TotalAlloc)
|
||||||
|
@ -127,11 +127,12 @@ func TestUitoa(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func numAllocations(f func()) int {
|
func numAllocations(f func()) int {
|
||||||
runtime.UpdateMemStats()
|
memstats := new(runtime.MemStats)
|
||||||
n0 := runtime.MemStats.Mallocs
|
runtime.ReadMemStats(memstats)
|
||||||
|
n0 := memstats.Mallocs
|
||||||
f()
|
f()
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
return int(runtime.MemStats.Mallocs - n0)
|
return int(memstats.Mallocs - n0)
|
||||||
}
|
}
|
||||||
|
|
||||||
var globalBuf [64]byte
|
var globalBuf [64]byte
|
||||||
|
@ -73,7 +73,7 @@ func parseDir(dirpath string) map[string]*ast.Package {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
st := &runtime.MemStats
|
st := new(runtime.MemStats)
|
||||||
packages = append(packages, packages...)
|
packages = append(packages, packages...)
|
||||||
packages = append(packages, packages...)
|
packages = append(packages, packages...)
|
||||||
n := flag.Int("n", 4, "iterations")
|
n := flag.Int("n", 4, "iterations")
|
||||||
@ -83,14 +83,17 @@ func main() {
|
|||||||
|
|
||||||
var lastParsed []map[string]*ast.Package
|
var lastParsed []map[string]*ast.Package
|
||||||
var t0 time.Time
|
var t0 time.Time
|
||||||
|
var numGC uint32
|
||||||
|
var pauseTotalNs uint64
|
||||||
pkgroot := runtime.GOROOT() + "/src/pkg/"
|
pkgroot := runtime.GOROOT() + "/src/pkg/"
|
||||||
for pass := 0; pass < 2; pass++ {
|
for pass := 0; pass < 2; pass++ {
|
||||||
// Once the heap is grown to full size, reset counters.
|
// Once the heap is grown to full size, reset counters.
|
||||||
// This hides the start-up pauses, which are much smaller
|
// This hides the start-up pauses, which are much smaller
|
||||||
// than the normal pauses and would otherwise make
|
// than the normal pauses and would otherwise make
|
||||||
// the average look much better than it actually is.
|
// the average look much better than it actually is.
|
||||||
st.NumGC = 0
|
runtime.ReadMemStats(st)
|
||||||
st.PauseTotalNs = 0
|
numGC = st.NumGC
|
||||||
|
pauseTotalNs = st.PauseTotalNs
|
||||||
t0 = time.Now()
|
t0 = time.Now()
|
||||||
|
|
||||||
for i := 0; i < *n; i++ {
|
for i := 0; i < *n; i++ {
|
||||||
@ -107,6 +110,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
t1 := time.Now()
|
t1 := time.Now()
|
||||||
|
|
||||||
|
runtime.ReadMemStats(st)
|
||||||
|
st.NumGC -= numGC
|
||||||
|
st.PauseTotalNs -= pauseTotalNs
|
||||||
fmt.Printf("Alloc=%d/%d Heap=%d Mallocs=%d PauseTime=%.3f/%d = %.3f\n",
|
fmt.Printf("Alloc=%d/%d Heap=%d Mallocs=%d PauseTime=%.3f/%d = %.3f\n",
|
||||||
st.Alloc, st.TotalAlloc,
|
st.Alloc, st.TotalAlloc,
|
||||||
st.Sys,
|
st.Sys,
|
||||||
@ -142,9 +148,7 @@ var packages = []string{
|
|||||||
"container/list",
|
"container/list",
|
||||||
"container/ring",
|
"container/ring",
|
||||||
"crypto/aes",
|
"crypto/aes",
|
||||||
"crypto/blowfish",
|
|
||||||
"crypto/hmac",
|
"crypto/hmac",
|
||||||
"crypto/md4",
|
|
||||||
"crypto/md5",
|
"crypto/md5",
|
||||||
"crypto/rand",
|
"crypto/rand",
|
||||||
"crypto/rc4",
|
"crypto/rc4",
|
||||||
@ -155,7 +159,6 @@ var packages = []string{
|
|||||||
"crypto/subtle",
|
"crypto/subtle",
|
||||||
"crypto/tls",
|
"crypto/tls",
|
||||||
"crypto/x509",
|
"crypto/x509",
|
||||||
"crypto/xtea",
|
|
||||||
"debug/dwarf",
|
"debug/dwarf",
|
||||||
"debug/macho",
|
"debug/macho",
|
||||||
"debug/elf",
|
"debug/elf",
|
||||||
@ -164,7 +167,6 @@ var packages = []string{
|
|||||||
"encoding/ascii85",
|
"encoding/ascii85",
|
||||||
"encoding/base64",
|
"encoding/base64",
|
||||||
"encoding/binary",
|
"encoding/binary",
|
||||||
"encoding/git85",
|
|
||||||
"encoding/hex",
|
"encoding/hex",
|
||||||
"encoding/pem",
|
"encoding/pem",
|
||||||
"os/exec",
|
"os/exec",
|
||||||
@ -193,8 +195,7 @@ var packages = []string{
|
|||||||
"mime",
|
"mime",
|
||||||
"net",
|
"net",
|
||||||
"os",
|
"os",
|
||||||
"os/signal",
|
"exp/signal",
|
||||||
"patch",
|
|
||||||
"path",
|
"path",
|
||||||
"math/rand",
|
"math/rand",
|
||||||
"reflect",
|
"reflect",
|
||||||
@ -219,6 +220,5 @@ var packages = []string{
|
|||||||
"unicode",
|
"unicode",
|
||||||
"unicode/utf8",
|
"unicode/utf8",
|
||||||
"unicode/utf16",
|
"unicode/utf16",
|
||||||
"websocket",
|
|
||||||
"encoding/xml",
|
"encoding/xml",
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func gcstats(name string, n int, t time.Duration) {
|
func gcstats(name string, n int, t time.Duration) {
|
||||||
st := &runtime.MemStats
|
st := new(runtime.MemStats)
|
||||||
|
runtime.ReadMemStats(st)
|
||||||
fmt.Printf("garbage.%sMem Alloc=%d/%d Heap=%d NextGC=%d Mallocs=%d\n", name, st.Alloc, st.TotalAlloc, st.Sys, st.NextGC, st.Mallocs)
|
fmt.Printf("garbage.%sMem Alloc=%d/%d Heap=%d NextGC=%d Mallocs=%d\n", name, st.Alloc, st.TotalAlloc, st.Sys, st.NextGC, st.Mallocs)
|
||||||
fmt.Printf("garbage.%s %d %d ns/op\n", name, n, t.Nanoseconds()/int64(n))
|
fmt.Printf("garbage.%s %d %d ns/op\n", name, n, t.Nanoseconds()/int64(n))
|
||||||
fmt.Printf("garbage.%sLastPause 1 %d ns/op\n", name, st.PauseNs[(st.NumGC-1)%uint32(len(st.PauseNs))])
|
fmt.Printf("garbage.%sLastPause 1 %d ns/op\n", name, st.PauseNs[(st.NumGC-1)%uint32(len(st.PauseNs))])
|
||||||
|
@ -30,6 +30,7 @@ var (
|
|||||||
heap *Object
|
heap *Object
|
||||||
calls [20]int
|
calls [20]int
|
||||||
numobjects int64
|
numobjects int64
|
||||||
|
memstats runtime.MemStats
|
||||||
)
|
)
|
||||||
|
|
||||||
func buildHeap() {
|
func buildHeap() {
|
||||||
@ -55,10 +56,10 @@ func buildTree(objsize, size float64, depth int) (*Object, float64) {
|
|||||||
|
|
||||||
func gc() {
|
func gc() {
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(&memstats)
|
||||||
pause := runtime.MemStats.PauseTotalNs
|
pause := memstats.PauseTotalNs
|
||||||
inuse := runtime.MemStats.Alloc
|
inuse := memstats.Alloc
|
||||||
free := runtime.MemStats.TotalAlloc - inuse
|
free := memstats.TotalAlloc - inuse
|
||||||
fmt.Printf("gc pause: %8.3f ms; collect: %8.0f MB; heapsize: %8.0f MB\n",
|
fmt.Printf("gc pause: %8.3f ms; collect: %8.0f MB; heapsize: %8.0f MB\n",
|
||||||
float64(pause-lastPauseNs)/1e6,
|
float64(pause-lastPauseNs)/1e6,
|
||||||
float64(free-lastFree)/1048576,
|
float64(free-lastFree)/1048576,
|
||||||
@ -71,9 +72,9 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
buildHeap()
|
buildHeap()
|
||||||
runtime.GOMAXPROCS(*cpus)
|
runtime.GOMAXPROCS(*cpus)
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(&memstats)
|
||||||
lastPauseNs = runtime.MemStats.PauseTotalNs
|
lastPauseNs = memstats.PauseTotalNs
|
||||||
lastFree = runtime.MemStats.TotalAlloc - runtime.MemStats.Alloc
|
lastFree = memstats.TotalAlloc - memstats.Alloc
|
||||||
if *cpuprofile != "" {
|
if *cpuprofile != "" {
|
||||||
f, err := os.Create(*cpuprofile)
|
f, err := os.Create(*cpuprofile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -35,14 +35,17 @@ func main() {
|
|||||||
go sender(c, 100000)
|
go sender(c, 100000)
|
||||||
receiver(c, dummy, 100000)
|
receiver(c, dummy, 100000)
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
runtime.MemStats.Alloc = 0
|
memstats := new(runtime.MemStats)
|
||||||
|
runtime.ReadMemStats(memstats)
|
||||||
|
alloc := memstats.Alloc
|
||||||
|
|
||||||
// second time shouldn't increase footprint by much
|
// second time shouldn't increase footprint by much
|
||||||
go sender(c, 100000)
|
go sender(c, 100000)
|
||||||
receiver(c, dummy, 100000)
|
receiver(c, dummy, 100000)
|
||||||
runtime.GC()
|
runtime.GC()
|
||||||
|
runtime.ReadMemStats(memstats)
|
||||||
|
|
||||||
if runtime.MemStats.Alloc > 1e5 {
|
if memstats.Alloc-alloc > 1e5 {
|
||||||
println("BUG: too much memory for 100,000 selects:", runtime.MemStats.Alloc)
|
println("BUG: too much memory for 100,000 selects:", memstats.Alloc-alloc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,9 @@ func main() {
|
|||||||
go h()
|
go h()
|
||||||
check([]int{100, 200, 101, 201, 500, 101, 201, 500})
|
check([]int{100, 200, 101, 201, 500, 101, 201, 500})
|
||||||
|
|
||||||
runtime.UpdateMemStats()
|
memstats := new(runtime.MemStats)
|
||||||
n0 := runtime.MemStats.Mallocs
|
runtime.ReadMemStats(memstats)
|
||||||
|
n0 := memstats.Mallocs
|
||||||
|
|
||||||
x, y := newfunc(), newfunc()
|
x, y := newfunc(), newfunc()
|
||||||
if x(1) != 1 || y(2) != 2 {
|
if x(1) != 1 || y(2) != 2 {
|
||||||
@ -101,8 +102,8 @@ func main() {
|
|||||||
fail = true
|
fail = true
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
if n0 != runtime.MemStats.Mallocs {
|
if n0 != memstats.Mallocs {
|
||||||
println("newfunc allocated unexpectedly")
|
println("newfunc allocated unexpectedly")
|
||||||
fail = true
|
fail = true
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
const N = 10000
|
const N = 10000
|
||||||
st := runtime.MemStats
|
st := new(runtime.MemStats)
|
||||||
|
memstats := new(runtime.MemStats)
|
||||||
|
runtime.ReadMemStats(st)
|
||||||
for i := 0; i < N; i++ {
|
for i := 0; i < N; i++ {
|
||||||
c := make(chan int, 10)
|
c := make(chan int, 10)
|
||||||
_ = c
|
_ = c
|
||||||
@ -33,8 +35,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
obj := runtime.MemStats.HeapObjects - st.HeapObjects
|
obj := memstats.HeapObjects - st.HeapObjects
|
||||||
if obj > N/5 {
|
if obj > N/5 {
|
||||||
fmt.Println("too many objects left:", obj)
|
fmt.Println("too many objects left:", obj)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@ -17,9 +17,10 @@ func init() {
|
|||||||
go send(c)
|
go send(c)
|
||||||
<-c
|
<-c
|
||||||
|
|
||||||
const chunk = 1<<20
|
const chunk = 1 << 20
|
||||||
runtime.UpdateMemStats()
|
memstats := new(runtime.MemStats)
|
||||||
sys := runtime.MemStats.Sys
|
runtime.ReadMemStats(memstats)
|
||||||
|
sys := memstats.Sys
|
||||||
b := make([]byte, chunk)
|
b := make([]byte, chunk)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
b[i] = byte(i%10 + '0')
|
b[i] = byte(i%10 + '0')
|
||||||
@ -28,8 +29,8 @@ func init() {
|
|||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
x = []byte(s)
|
x = []byte(s)
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
sys1 := runtime.MemStats.Sys
|
sys1 := memstats.Sys
|
||||||
if sys1-sys > chunk*50 {
|
if sys1-sys > chunk*50 {
|
||||||
println("allocated 1000 chunks of", chunk, "and used ", sys1-sys, "memory")
|
println("allocated 1000 chunks of", chunk, "and used ", sys1-sys, "memory")
|
||||||
}
|
}
|
||||||
@ -41,4 +42,3 @@ func send(c chan int) {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,9 +17,10 @@ import (
|
|||||||
var chatty = flag.Bool("v", false, "chatty")
|
var chatty = flag.Bool("v", false, "chatty")
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
memstats := new(runtime.MemStats)
|
||||||
runtime.Free(runtime.Alloc(1))
|
runtime.Free(runtime.Alloc(1))
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(memstats)
|
||||||
if *chatty {
|
if *chatty {
|
||||||
fmt.Printf("%+v %v\n", runtime.MemStats, uint64(0))
|
fmt.Printf("%+v %v\n", memstats, uint64(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,9 @@ var footprint uint64
|
|||||||
var allocated uint64
|
var allocated uint64
|
||||||
|
|
||||||
func bigger() {
|
func bigger() {
|
||||||
runtime.UpdateMemStats()
|
memstats := new(runtime.MemStats)
|
||||||
if f := runtime.MemStats.Sys; footprint < f {
|
runtime.ReadMemStats(memstats)
|
||||||
|
if f := memstats.Sys; footprint < f {
|
||||||
footprint = f
|
footprint = f
|
||||||
if *chatty {
|
if *chatty {
|
||||||
println("Footprint", footprint, " for ", allocated)
|
println("Footprint", footprint, " for ", allocated)
|
||||||
|
@ -16,10 +16,12 @@ import (
|
|||||||
var chatty = flag.Bool("v", false, "chatty")
|
var chatty = flag.Bool("v", false, "chatty")
|
||||||
|
|
||||||
var oldsys uint64
|
var oldsys uint64
|
||||||
|
var memstats runtime.MemStats
|
||||||
|
|
||||||
func bigger() {
|
func bigger() {
|
||||||
runtime.UpdateMemStats()
|
st := &memstats
|
||||||
if st := runtime.MemStats; oldsys < st.Sys {
|
runtime.ReadMemStats(st)
|
||||||
|
if oldsys < st.Sys {
|
||||||
oldsys = st.Sys
|
oldsys = st.Sys
|
||||||
if *chatty {
|
if *chatty {
|
||||||
println(st.Sys, " system bytes for ", st.Alloc, " Go bytes")
|
println(st.Sys, " system bytes for ", st.Alloc, " Go bytes")
|
||||||
@ -33,25 +35,25 @@ func bigger() {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
runtime.GC() // clean up garbage from init
|
runtime.GC() // clean up garbage from init
|
||||||
runtime.UpdateMemStats() // first call can do some allocations
|
runtime.ReadMemStats(&memstats) // first call can do some allocations
|
||||||
runtime.MemProfileRate = 0 // disable profiler
|
runtime.MemProfileRate = 0 // disable profiler
|
||||||
runtime.MemStats.Alloc = 0 // ignore stacks
|
stacks := memstats.Alloc // ignore stacks
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
for i := 0; i < 1<<7; i++ {
|
for i := 0; i < 1<<7; i++ {
|
||||||
for j := 1; j <= 1<<22; j <<= 1 {
|
for j := 1; j <= 1<<22; j <<= 1 {
|
||||||
if i == 0 && *chatty {
|
if i == 0 && *chatty {
|
||||||
println("First alloc:", j)
|
println("First alloc:", j)
|
||||||
}
|
}
|
||||||
if a := runtime.MemStats.Alloc; a != 0 {
|
if a := memstats.Alloc - stacks; a != 0 {
|
||||||
println("no allocations but stats report", a, "bytes allocated")
|
println("no allocations but stats report", a, "bytes allocated")
|
||||||
panic("fail")
|
panic("fail")
|
||||||
}
|
}
|
||||||
b := runtime.Alloc(uintptr(j))
|
b := runtime.Alloc(uintptr(j))
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(&memstats)
|
||||||
during := runtime.MemStats.Alloc
|
during := memstats.Alloc - stacks
|
||||||
runtime.Free(b)
|
runtime.Free(b)
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(&memstats)
|
||||||
if a := runtime.MemStats.Alloc; a != 0 {
|
if a := memstats.Alloc - stacks; a != 0 {
|
||||||
println("allocated ", j, ": wrong stats: during=", during, " after=", a, " (want 0)")
|
println("allocated ", j, ": wrong stats: during=", during, " after=", a, " (want 0)")
|
||||||
panic("fail")
|
panic("fail")
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ var reverse = flag.Bool("r", false, "reverse")
|
|||||||
var longtest = flag.Bool("l", false, "long test")
|
var longtest = flag.Bool("l", false, "long test")
|
||||||
|
|
||||||
var b []*byte
|
var b []*byte
|
||||||
var stats = &runtime.MemStats
|
var stats = new(runtime.MemStats)
|
||||||
|
|
||||||
func OkAmount(size, n uintptr) bool {
|
func OkAmount(size, n uintptr) bool {
|
||||||
if n < size {
|
if n < size {
|
||||||
@ -42,7 +42,7 @@ func AllocAndFree(size, count int) {
|
|||||||
if *chatty {
|
if *chatty {
|
||||||
fmt.Printf("size=%d count=%d ...\n", size, count)
|
fmt.Printf("size=%d count=%d ...\n", size, count)
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(stats)
|
||||||
n1 := stats.Alloc
|
n1 := stats.Alloc
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
b[i] = runtime.Alloc(uintptr(size))
|
b[i] = runtime.Alloc(uintptr(size))
|
||||||
@ -51,13 +51,13 @@ func AllocAndFree(size, count int) {
|
|||||||
println("lookup failed: got", base, n, "for", b[i])
|
println("lookup failed: got", base, n, "for", b[i])
|
||||||
panic("fail")
|
panic("fail")
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(stats)
|
||||||
if stats.Sys > 1e9 {
|
if stats.Sys > 1e9 {
|
||||||
println("too much memory allocated")
|
println("too much memory allocated")
|
||||||
panic("fail")
|
panic("fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(stats)
|
||||||
n2 := stats.Alloc
|
n2 := stats.Alloc
|
||||||
if *chatty {
|
if *chatty {
|
||||||
fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
|
fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
|
||||||
@ -75,17 +75,17 @@ func AllocAndFree(size, count int) {
|
|||||||
panic("fail")
|
panic("fail")
|
||||||
}
|
}
|
||||||
runtime.Free(b[i])
|
runtime.Free(b[i])
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(stats)
|
||||||
if stats.Alloc != uint64(alloc-n) {
|
if stats.Alloc != uint64(alloc-n) {
|
||||||
println("free alloc got", stats.Alloc, "expected", alloc-n, "after free of", n)
|
println("free alloc got", stats.Alloc, "expected", alloc-n, "after free of", n)
|
||||||
panic("fail")
|
panic("fail")
|
||||||
}
|
}
|
||||||
if runtime.MemStats.Sys > 1e9 {
|
if stats.Sys > 1e9 {
|
||||||
println("too much memory allocated")
|
println("too much memory allocated")
|
||||||
panic("fail")
|
panic("fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runtime.UpdateMemStats()
|
runtime.ReadMemStats(stats)
|
||||||
n4 := stats.Alloc
|
n4 := stats.Alloc
|
||||||
|
|
||||||
if *chatty {
|
if *chatty {
|
||||||
|
Loading…
Reference in New Issue
Block a user