public bool Trim() { Debug.Assert(s_trimBuffers); Debug.Assert(s_allTlsBuckets != null); int milliseconds = Environment.TickCount; MemoryPressure pressure = GetMemoryPressure(); ArrayPoolEventSource log = ArrayPoolEventSource.Log; if (log.IsEnabled()) { log.BufferTrimPoll(milliseconds, (int)pressure); } PerCoreLockedStacks?[] perCoreBuckets = _buckets; for (int i = 0; i < perCoreBuckets.Length; i++) { perCoreBuckets[i]?.Trim((uint)milliseconds, Id, pressure, _bucketArraySizes[i]); } if (pressure == MemoryPressure.High) { // Under high pressure, release all thread locals if (log.IsEnabled()) { foreach (KeyValuePair <T[]?[], object?> tlsBuckets in s_allTlsBuckets) { T[]?[] buckets = tlsBuckets.Key; for (int i = 0; i < buckets.Length; i++) { T[]? buffer = Interlocked.Exchange(ref buckets[i], null); if (buffer != null) { // As we don't want to take a perf hit in the rent path it // is possible that a buffer could be rented as we "free" it. log.BufferTrimmed(buffer.GetHashCode(), buffer.Length, Id); } } } } else { foreach (KeyValuePair <T[]?[], object?> tlsBuckets in s_allTlsBuckets) { T[]?[] buckets = tlsBuckets.Key; Array.Clear(buckets, 0, buckets.Length); } } } return(true); }
public bool Trim() { int milliseconds = Environment.TickCount; MemoryPressure pressure = GetMemoryPressure(); ArrayPoolEventSource log = ArrayPoolEventSource.Log; if (log.IsEnabled()) { log.BufferTrimPoll(milliseconds, (int)pressure); } foreach (PerCoreLockedStacks bucket in _buckets) { bucket?.Trim((uint)milliseconds, Id, pressure, _bucketArraySizes); } if (pressure == MemoryPressure.High) { // Under high pressure, release all thread locals foreach (KeyValuePair <T[][], object> tlsBuckets in s_AllTlsBuckets) { T[][] buckets = tlsBuckets.Key; for (int i = 0; i < NumBuckets; i++) { T[] buffer = buckets[i]; buckets[i] = null; if (log.IsEnabled() && buffer != null) { log.BufferTrimmed(buffer.GetHashCode(), buffer.Length, Id); } } } } return(true); }