1
0
mirror of https://github.com/golang/go synced 2024-11-20 01:14:40 -07:00

runtime: make next_gc be heap size to trigger GC at

In the STW collector, next_gc was both the heap size to trigger GC at
as well as the goal heap size.

Early in the concurrent collector's development, next_gc was the goal
heap size, but was also used as the heap size to trigger GC at. This
meant we always overshot the goal because of allocation during
concurrent GC.

Currently, next_gc is still the goal heap size, but we trigger
concurrent GC at 7/8*GOGC heap growth. This complicates
shouldtriggergc, but was necessary because of the incremental
maintenance of next_gc.

Now we simply compute next_gc for the next cycle during mark
termination. Hence, it's now easy to take the simpler route and
redefine next_gc as the heap size at which the next GC triggers. We
can directly compute this with the 7/8 backoff during mark termination
and shouldtriggergc can simply test if the live heap size has grown
over the next_gc trigger.

This will also simplify later changes once we start setting next_gc in
more sophisticated ways.

Change-Id: I872be4ae06b4f7a0d7f7967360a054bd36b90eea
Reviewed-on: https://go-review.googlesource.com/8420
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Austin Clements 2015-03-31 11:44:11 -04:00
parent d7e0ad4b82
commit 6d12b1780e

View File

@ -180,11 +180,6 @@ func setGCPercent(in int32) (out int32) {
return out return out
} }
// Trigger the concurrent GC when 1/triggerratio memory is available to allocate.
// Adjust this ratio as part of a scheme to ensure that mutators have enough
// memory to allocate in durring a concurrent GC cycle.
var triggerratio = int64(8)
// Determine whether to initiate a GC. // Determine whether to initiate a GC.
// If the GC is already working no need to trigger another one. // If the GC is already working no need to trigger another one.
// This should establish a feedback loop where if the GC does not // This should establish a feedback loop where if the GC does not
@ -195,7 +190,7 @@ var triggerratio = int64(8)
// A false negative simple does not start a GC, a false positive // A false negative simple does not start a GC, a false positive
// will start a GC needlessly. Neither have correctness issues. // will start a GC needlessly. Neither have correctness issues.
func shouldtriggergc() bool { func shouldtriggergc() bool {
return triggerratio*(int64(memstats.next_gc)-int64(memstats.heap_live)) <= int64(memstats.next_gc) && atomicloaduint(&bggc.working) == 0 return memstats.heap_live >= memstats.next_gc && atomicloaduint(&bggc.working) == 0
} }
var work struct { var work struct {
@ -591,9 +586,10 @@ func gcMark(start_time int64) {
cachestats() cachestats()
// compute next_gc // Trigger the next GC cycle when the allocated heap has
// reached 7/8ths of the growth allowed by gcpercent.
memstats.heap_live = work.bytesMarked memstats.heap_live = work.bytesMarked
memstats.next_gc = memstats.heap_live + memstats.heap_live*uint64(gcpercent)/100 memstats.next_gc = memstats.heap_live + (memstats.heap_live*uint64(gcpercent)/100)*7/8
if memstats.next_gc < heapminimum { if memstats.next_gc < heapminimum {
memstats.next_gc = heapminimum memstats.next_gc = heapminimum
} }