aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mgc.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2019-11-19 17:32:17 +0000
committerMichael Knyszek <mknyszek@google.com>2020-04-30 18:12:03 +0000
commit2491c5fd2451783e4ba6630345805de1e7761e3b (patch)
treeef09e22883f9255205149eba2515c7fb60e5d09a /src/runtime/mgc.go
parentc7915376ce3cdd172bf71ca4127c67f196b8e43e (diff)
downloadgo-2491c5fd2451783e4ba6630345805de1e7761e3b.tar.gz
go-2491c5fd2451783e4ba6630345805de1e7761e3b.zip
runtime: wake scavenger and update address on sweep done
This change modifies the semantics of waking the scavenger: rather than wake on any update to pacing, wake when we know we will have work to do, that is, when the sweeper is done. The current scavenger runs over the address space just once per GC cycle, and we want to maximize the chance that the scavenger observes the most attractive scavengable memory in that pass (i.e. free memory with the highest address), so the timing is important. By having the scavenger awaken and reset its search space when the sweeper is done, we increase the chance that the scavenger will observe the most attractive scavengable memory, because no more memory will be freed that GC cycle (so the highest scavengable address should now be available). Furthermore, in applications that go idle, this means the background scavenger will be awoken even if another GC doesn't happen, which isn't true today. However, we're unable to wake the scavenger directly from within the sweeper; waking the scavenger involves modifying timers and readying goroutines, the latter of which may trigger an allocation today (and the sweeper may run during allocation!). Instead, we do the following: 1. Set a flag which is checked by sysmon. sysmon will clear the flag and wake the scavenger. 2. Wake the scavenger unconditionally at sweep termination. The idea behind this policy is that it gets us close enough to the state above without having to deal with the complexity of waking the scavenger in deep parts of the runtime. If the application goes idle and sweeping finishes (so we don't reach sweep termination), then sysmon will wake the scavenger. sysmon has a worst-case 20 ms delay in responding to this signal, which is probably fine if the application is completely idle anyway, but if the application is actively allocating, then the proportional sweeper should help ensure that sweeping ends very close to sweep termination, so sweep termination is a perfectly reasonable time to wake up the scavenger. Updates #35788. Change-Id: I84289b37816a7d595d803c72a71b7f5c59d47e6b Reviewed-on: https://go-review.googlesource.com/c/go/+/207998 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/mgc.go')
-rw-r--r--src/runtime/mgc.go5
1 files changed, 0 insertions, 5 deletions
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 3c4d807bac..b3499516f6 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -236,8 +236,6 @@ func setGCPercent(in int32) (out int32) {
gcSetTriggerRatio(memstats.triggerRatio)
unlock(&mheap_.lock)
})
- // Pacing changed, so the scavenger should be awoken.
- wakeScavenger()
// If we just disabled GC, wait for any concurrent GC mark to
// finish so we always return with no GC running.
@@ -1707,9 +1705,6 @@ func gcMarkTermination(nextTriggerRatio float64) {
// Update GC trigger and pacing for the next cycle.
gcSetTriggerRatio(nextTriggerRatio)
- // Pacing changed, so the scavenger should be awoken.
- wakeScavenger()
-
// Update timing memstats
now := nanotime()
sec, nsec, _ := time_now()