}
// 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
+// UpdateMemStats brings MemStats up to date.
+func UpdateMemStats()
+
// GC runs a garbage collection.
func GC()
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
runfinq(void)
{
}
}
}
-
+
+ runtime.UpdateMemStats()
obj := runtime.MemStats.HeapObjects - st.HeapObjects
if obj > N/5 {
fmt.Println("too many objects left:", obj)
func main() {
runtime.Free(runtime.Alloc(1))
+ runtime.UpdateMemStats()
if *chatty {
fmt.Printf("%+v %v\n", runtime.MemStats, uint64(0))
}
var allocated uint64
func bigger() {
+ runtime.UpdateMemStats()
if f := runtime.MemStats.Sys; footprint < f {
footprint = f
if *chatty {
var oldsys uint64
func bigger() {
+ runtime.UpdateMemStats()
if st := runtime.MemStats; oldsys < st.Sys {
oldsys = st.Sys
if *chatty {
}
func main() {
- runtime.GC() // clean up garbage from init
+ runtime.GC() // clean up garbage from init
runtime.MemProfileRate = 0 // disable profiler
runtime.MemStats.Alloc = 0 // ignore stacks
flag.Parse()
panic("fail")
}
b := runtime.Alloc(uintptr(j))
+ runtime.UpdateMemStats()
during := runtime.MemStats.Alloc
runtime.Free(b)
- runtime.GC()
+ runtime.UpdateMemStats()
if a := runtime.MemStats.Alloc; a != 0 {
println("allocated ", j, ": wrong stats: during=", during, " after=", a, " (want 0)")
panic("fail")
if *chatty {
fmt.Printf("size=%d count=%d ...\n", size, count)
}
+ runtime.UpdateMemStats()
n1 := stats.Alloc
for i := 0; i < count; i++ {
b[i] = runtime.Alloc(uintptr(size))
println("lookup failed: got", base, n, "for", b[i])
panic("fail")
}
- if runtime.MemStats.Sys > 1e9 {
+ runtime.UpdateMemStats()
+ if stats.Sys > 1e9 {
println("too much memory allocated")
panic("fail")
}
}
+ runtime.UpdateMemStats()
n2 := stats.Alloc
if *chatty {
fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
}
n3 := stats.Alloc
- runtime.GC()
for j := 0; j < count; j++ {
i := j
if *reverse {
panic("fail")
}
runtime.Free(b[i])
- runtime.GC()
+ runtime.UpdateMemStats()
if stats.Alloc != uint64(alloc-n) {
println("free alloc got", stats.Alloc, "expected", alloc-n, "after free of", n)
panic("fail")
panic("fail")
}
}
+ runtime.UpdateMemStats()
n4 := stats.Alloc
if *chatty {