1
0
mirror of https://github.com/golang/go synced 2024-11-22 03:44:39 -07:00

runtime: add UpdateMemStats, use in tests

Drops mallocrep1.go back to a reasonable
amount of time.  (154 -> 0.8 seconds on my Mac)

Fixes #2085.

R=golang-dev, dvyukov, r
CC=golang-dev
https://golang.org/cl/4811045
This commit is contained in:
Russ Cox 2011-07-22 00:55:01 -04:00
parent 222450addb
commit 226fb099d9
7 changed files with 36 additions and 7 deletions

View File

@ -62,8 +62,13 @@ func init() {
} }
// MemStats holds statistics about the memory system. // MemStats holds statistics about the memory system.
// The statistics are only approximate, as they are not interlocked on update. // The statistics may be out of date, as the information is
// updated lazily from per-thread caches.
// Use UpdateMemStats to bring the statistics up to date.
var MemStats MemStatsType 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()

View File

@ -663,6 +663,22 @@ runtime·gc(int32 force)
runtime·gc(1); runtime·gc(1);
} }
void
runtime·UpdateMemStats(void)
{
// Have to acquire gcsema 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.
runtime·semacquire(&gcsema);
m->gcing = 1;
runtime·stoptheworld();
cachestats();
m->gcing = 0;
runtime·semrelease(&gcsema);
runtime·starttheworld();
}
static void static void
runfinq(void) runfinq(void)
{ {

View File

@ -33,6 +33,7 @@ func main() {
} }
} }
runtime.UpdateMemStats()
obj := runtime.MemStats.HeapObjects - st.HeapObjects obj := runtime.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)

View File

@ -18,6 +18,7 @@ var chatty = flag.Bool("v", false, "chatty")
func main() { func main() {
runtime.Free(runtime.Alloc(1)) runtime.Free(runtime.Alloc(1))
runtime.UpdateMemStats()
if *chatty { if *chatty {
fmt.Printf("%+v %v\n", runtime.MemStats, uint64(0)) fmt.Printf("%+v %v\n", runtime.MemStats, uint64(0))
} }

View File

@ -21,6 +21,7 @@ var footprint uint64
var allocated uint64 var allocated uint64
func bigger() { func bigger() {
runtime.UpdateMemStats()
if f := runtime.MemStats.Sys; footprint < f { if f := runtime.MemStats.Sys; footprint < f {
footprint = f footprint = f
if *chatty { if *chatty {

View File

@ -18,6 +18,7 @@ var chatty = flag.Bool("v", false, "chatty")
var oldsys uint64 var oldsys uint64
func bigger() { func bigger() {
runtime.UpdateMemStats()
if st := runtime.MemStats; oldsys < st.Sys { if st := runtime.MemStats; oldsys < st.Sys {
oldsys = st.Sys oldsys = st.Sys
if *chatty { if *chatty {
@ -45,9 +46,10 @@ func main() {
panic("fail") panic("fail")
} }
b := runtime.Alloc(uintptr(j)) b := runtime.Alloc(uintptr(j))
runtime.UpdateMemStats()
during := runtime.MemStats.Alloc during := runtime.MemStats.Alloc
runtime.Free(b) runtime.Free(b)
runtime.GC() runtime.UpdateMemStats()
if a := runtime.MemStats.Alloc; a != 0 { if a := runtime.MemStats.Alloc; 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")

View File

@ -42,6 +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()
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))
@ -50,17 +51,18 @@ 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")
} }
if runtime.MemStats.Sys > 1e9 { runtime.UpdateMemStats()
if stats.Sys > 1e9 {
println("too much memory allocated") println("too much memory allocated")
panic("fail") panic("fail")
} }
} }
runtime.UpdateMemStats()
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)
} }
n3 := stats.Alloc n3 := stats.Alloc
runtime.GC()
for j := 0; j < count; j++ { for j := 0; j < count; j++ {
i := j i := j
if *reverse { if *reverse {
@ -73,7 +75,7 @@ func AllocAndFree(size, count int) {
panic("fail") panic("fail")
} }
runtime.Free(b[i]) runtime.Free(b[i])
runtime.GC() runtime.UpdateMemStats()
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")
@ -83,6 +85,7 @@ func AllocAndFree(size, count int) {
panic("fail") panic("fail")
} }
} }
runtime.UpdateMemStats()
n4 := stats.Alloc n4 := stats.Alloc
if *chatty { if *chatty {