Commit b6e178ed authored by Rick Hudson's avatar Rick Hudson

runtime: set heap minimum default based on GOGC

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/9814Reviewed-by: 's avatarAustin Clements <austin@google.com>
Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
parent 7bdeab1b
...@@ -130,6 +130,9 @@ const ( ...@@ -130,6 +130,9 @@ const (
// heapminimum is the minimum number of bytes in the heap. // 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 // 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. // 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) var heapminimum = uint64(4 << 20)
// Initialized from $GOGC. GOGC=off means no GC. // Initialized from $GOGC. GOGC=off means no GC.
...@@ -141,7 +144,7 @@ func gcinit() { ...@@ -141,7 +144,7 @@ func gcinit() {
} }
work.markfor = parforalloc(_MaxGcproc) work.markfor = parforalloc(_MaxGcproc)
gcpercent = readgogc() _ = setGCPercent(readgogc())
for datap := &firstmoduledata; datap != nil; datap = datap.next { for datap := &firstmoduledata; datap != nil; datap = datap.next {
datap.gcdatamask = unrollglobgcprog((*byte)(unsafe.Pointer(datap.gcdata)), datap.edata-datap.data) datap.gcdatamask = unrollglobgcprog((*byte)(unsafe.Pointer(datap.gcdata)), datap.edata-datap.data)
datap.gcbssmask = unrollglobgcprog((*byte)(unsafe.Pointer(datap.gcbss)), datap.ebss-datap.bss) datap.gcbssmask = unrollglobgcprog((*byte)(unsafe.Pointer(datap.gcbss)), datap.ebss-datap.bss)
...@@ -149,6 +152,17 @@ func gcinit() { ...@@ -149,6 +152,17 @@ func gcinit() {
memstats.next_gc = heapminimum 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, // gcenable is called after the bulk of the runtime initialization,
// just before we're about to start letting user code run. // just before we're about to start letting user code run.
// It kicks off the background sweeper goroutine and enables GC. // It kicks off the background sweeper goroutine and enables GC.
...@@ -166,6 +180,7 @@ func setGCPercent(in int32) (out int32) { ...@@ -166,6 +180,7 @@ func setGCPercent(in int32) (out int32) {
in = -1 in = -1
} }
gcpercent = in gcpercent = in
heapminimum = heapminimum * uint64(gcpercent) / 100
unlock(&mheap_.lock) unlock(&mheap_.lock)
return out return out
} }
......
...@@ -432,15 +432,3 @@ func reflect_typelinks() [][]*_type { ...@@ -432,15 +432,3 @@ func reflect_typelinks() [][]*_type {
} }
return ret 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))
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment