// This is accessed atomically.
reclaimCredit uintptr
+ // scavengeCredit is spare credit for extra bytes scavenged.
+ // Since the scavenging mechanisms operate on spans, it may
+ // scavenge more than requested. Any spare pages released
+ // go to this credit pool.
+ //
+ // This is protected by the mheap lock.
+ scavengeCredit uintptr
+
// Malloc stats.
largealloc uint64 // bytes allocated for large objects
nlargealloc uint64 // number of large object allocations
// simply blocking GC (by disabling preemption).
sweepArenas []arenaIdx
- _ uint32 // ensure 64-bit alignment of central
+ // _ uint32 // ensure 64-bit alignment of central
// central free lists for small size classes.
// the padding makes sure that the mcentrals are
// starting from the largest span and working down. It then takes those spans
// and places them in scav. h must be locked.
func (h *mheap) scavengeLargest(nbytes uintptr) {
+ // Use up scavenge credit if there's any available.
+ if nbytes > h.scavengeCredit {
+ nbytes -= h.scavengeCredit
+ h.scavengeCredit = 0
+ } else {
+ h.scavengeCredit -= nbytes
+ return
+ }
// Iterate over the treap backwards (from largest to smallest) scavenging spans
// until we've reached our quota of nbytes.
released := uintptr(0)
h.scav.insert(s)
released += r
}
+ // If we over-scavenged, turn that extra amount into credit.
+ if released > nbytes {
+ h.scavengeCredit += released - nbytes
+ }
}
// scavengeAll visits each node in the unscav treap and scavenges the