]> Cypherpunks.ru repositories - gostls13.git/commitdiff
runtime: flush each idle P's page cache at the end of each GC cycle
authorMichael Anthony Knyszek <mknyszek@google.com>
Mon, 28 Nov 2022 19:53:20 +0000 (19:53 +0000)
committerGopher Robot <gobot@golang.org>
Wed, 5 Apr 2023 21:45:24 +0000 (21:45 +0000)
Currently pages may linger in an idle P's page cache, hiding the memory
from the scavenger precisely when it's useful to return memory to the OS
and reduce the application's footprint.

Change-Id: I49fbcd806b6c66991d1ca87949f76a9f06708e70
Reviewed-on: https://go-review.googlesource.com/c/go/+/453622
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>

src/runtime/mgc.go

index f630577914868dcc770477dd46117cd9af77ceb7..7c7d1449a2e08a0004f0f7b99cca38de483761ee 100644 (file)
@@ -1104,9 +1104,21 @@ func gcMarkTermination() {
        // mcache before allocating, but idle Ps may not. Since this
        // is necessary to sweep all spans, we need to ensure all
        // mcaches are flushed before we start the next GC cycle.
+       //
+       // While we're here, flush the page cache for idle Ps to avoid
+       // having pages get stuck on them. These pages are hidden from
+       // the scavenger, so in small idle heaps a significant amount
+       // of additional memory might be held onto.
        systemstack(func() {
                forEachP(func(pp *p) {
                        pp.mcache.prepareForSweep()
+                       if pp.status == _Pidle {
+                               systemstack(func() {
+                                       lock(&mheap_.lock)
+                                       pp.pcache.flush(&mheap_.pages)
+                                       unlock(&mheap_.lock)
+                               })
+                       }
                })
        })
        // Now that we've swept stale spans in mcaches, they don't