aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/malloc.go
diff options
context:
space:
mode:
authorRhys Hiltner <rhys@justin.tv>2022-04-01 12:56:49 -0700
committerMichael Knyszek <mknyszek@google.com>2022-05-03 20:49:59 +0000
commit89c0dd829f49c91eb2636bc2b24df0b1cdc74a1c (patch)
tree023405e41da4231e1925c85a04e9f0bf9ac58e0c /src/runtime/malloc.go
parent2c0a9884e0dc930c1a3596bc1decf183c8fdcf77 (diff)
downloadgo-89c0dd829f49c91eb2636bc2b24df0b1cdc74a1c.tar.xz
runtime: split mprof locks
The profiles for memory allocations, sync.Mutex contention, and general blocking store their data in a shared hash table. The bookkeeping work at the end of a garbage collection cycle involves maintenance on each memory allocation record. Previously, a single lock guarded access to the hash table and the contents of all records. When a program has allocated memory at a large number of unique call stacks, the maintenance following every garbage collection can hold that lock for several milliseconds. That can prevent progress on all other goroutines by delaying acquirep's call to mcache.prepareForSweep, which needs the lock in mProf_Free to report when a profiled allocation is no longer in use. With no user goroutines making progress, it is in effect a multi-millisecond GC-related stop-the-world pause. Split the lock so the call to mProf_Flush no longer delays each P's call to mProf_Free: mProf_Free uses a lock on the memory records' N+1 cycle, and mProf_Flush uses locks on the memory records' accumulator and their N cycle. mProf_Malloc also no longer competes with mProf_Flush, as it uses a lock on the memory records' N+2 cycle. The profiles for sync.Mutex contention and general blocking now share a separate lock, and another lock guards insertions to the shared hash table (uncommon in the steady-state). Consumers of each type of profile take the matching accumulator lock, so will observe consistent count and magnitude values for each record. For #45894 Change-Id: I615ff80618d10e71025423daa64b0b7f9dc57daa Reviewed-on: https://go-review.googlesource.com/c/go/+/399956 Reviewed-by: Carlos Amedee <carlos@golang.org> Run-TryBot: Rhys Hiltner <rhys@justin.tv> Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/runtime/malloc.go')
-rw-r--r--src/runtime/malloc.go7
1 files changed, 6 insertions, 1 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index f65be2bc74..14bf9a583f 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -413,7 +413,12 @@ func mallocinit() {
mheap_.init()
mcache0 = allocmcache()
lockInit(&gcBitsArenas.lock, lockRankGcBitsArenas)
- lockInit(&proflock, lockRankProf)
+ lockInit(&profInsertLock, lockRankProfInsert)
+ lockInit(&profBlockLock, lockRankProfBlock)
+ lockInit(&profMemActiveLock, lockRankProfMemActive)
+ for i := range profMemFutureLock {
+ lockInit(&profMemFutureLock[i], lockRankProfMemFuture)
+ }
lockInit(&globalAlloc.mutex, lockRankGlobalAlloc)
// Create initial arena growth hints.