]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: set heap minimum default based on GOGC
authorRick Hudson <rlh@golang.org>
Wed, 6 May 2015 19:58:20 +0000 (15:58 -0400)
committerRick Hudson <rlh@golang.org>
Thu, 7 May 2015 21:05:58 +0000 (21:05 +0000)
Currently the heap minimum is set to 4MB which prevents our ability to
collect at every allocation by setting GOGC=0. This adjust the
heap minimum to 4MB*GOGC/100 thus reenabling collecting at every allocation.
Fixes #10681

Change-Id: I912d027dac4b14ae535597e8beefa9ac3fb8ad94
Reviewed-on: https://go-review.googlesource.com/9814
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
src/runtime/mgc.go
src/runtime/runtime1.go

index 90d5a12e93e98e1eacd7792faf44b4a15b1ef90b..9bd36d1a5eb68dab78d063da17214082d68e9b9a 100644 (file)
@@ -130,6 +130,9 @@ const (
 // heapminimum is the minimum number of bytes in the heap.
 // This cleans up the corner case of where we have a very small live set but a lot
 // of allocations and collecting every GOGC * live set is expensive.
+// heapminimum is adjust by multiplying it by GOGC/100. In
+// the special case of GOGC==0 this will set heapminimum to 0 resulting
+// collecting at every allocation even when the heap size is small.
 var heapminimum = uint64(4 << 20)
 
 // Initialized from $GOGC.  GOGC=off means no GC.
@@ -141,7 +144,7 @@ func gcinit() {
        }
 
        work.markfor = parforalloc(_MaxGcproc)
-       gcpercent = readgogc()
+       _ = setGCPercent(readgogc())
        for datap := &firstmoduledata; datap != nil; datap = datap.next {
                datap.gcdatamask = unrollglobgcprog((*byte)(unsafe.Pointer(datap.gcdata)), datap.edata-datap.data)
                datap.gcbssmask = unrollglobgcprog((*byte)(unsafe.Pointer(datap.gcbss)), datap.ebss-datap.bss)
@@ -149,6 +152,17 @@ func gcinit() {
        memstats.next_gc = heapminimum
 }
 
+func readgogc() int32 {
+       p := gogetenv("GOGC")
+       if p == "" {
+               return 100
+       }
+       if p == "off" {
+               return -1
+       }
+       return int32(atoi(p))
+}
+
 // gcenable is called after the bulk of the runtime initialization,
 // just before we're about to start letting user code run.
 // It kicks off the background sweeper goroutine and enables GC.
@@ -166,6 +180,7 @@ func setGCPercent(in int32) (out int32) {
                in = -1
        }
        gcpercent = in
+       heapminimum = heapminimum * uint64(gcpercent) / 100
        unlock(&mheap_.lock)
        return out
 }
index 2151be59f999274a76f1dcaaf4b9c2b2a87395f8..ea3883018b10280a589493945c72599a08d5f898 100644 (file)
@@ -432,15 +432,3 @@ func reflect_typelinks() [][]*_type {
        }
        return ret
 }
-
-// TODO: move back into mgc.go
-func readgogc() int32 {
-       p := gogetenv("GOGC")
-       if p == "" {
-               return 100
-       }
-       if p == "off" {
-               return -1
-       }
-       return int32(atoi(p))
-}