What's wrong
RingBuffer<T>.Clear() (Containers/RingBuffer.cs ~304) only resets the indices and the count:
public void Clear()
{
BackIndex = 0;
FrontIndex = 0;
Count = 0;
}
The backing array is left untouched. Every reference-type element that was logically removed stays reachable until a later PushBack overwrites its slot. If the buffer is never refilled, that never happens. Every other array-backed container in the library (ContiguousCollection, ContiguousSet, ContiguousMap) clears its references in Clear, and SpscRingBuffer clears each slot when it dequeues.
Repro (reproduced)
var rb = new RingBuffer<object>(4);
WeakReference wr = Fill(rb); // [NoInlining]: var o = new object(); rb.PushBack(o); return new WeakReference(o);
rb.Clear();
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
Console.WriteLine(wr.IsAlive); // Observed: True. The same test with ContiguousCollection<object> prints False.
Why it matters
Ring buffers usually hold recent large objects, such as frames, audio blocks or log entries. After Clear(), a buffer of N slots can keep up to N of them in memory for as long as the buffer itself lives.
Suggested fix
In Clear(), clear the array before resetting the indices when T contains references:
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) Array.Clear(Buffer, 0, Buffer.Length);
On netstandard targets, use !typeof(T).IsValueType, as the other containers do.
Acceptance: a WeakReference test shows that items are collectable after Clear().
What's wrong
RingBuffer<T>.Clear()(Containers/RingBuffer.cs~304) only resets the indices and the count:The backing array is left untouched. Every reference-type element that was logically removed stays reachable until a later
PushBackoverwrites its slot. If the buffer is never refilled, that never happens. Every other array-backed container in the library (ContiguousCollection,ContiguousSet,ContiguousMap) clears its references inClear, andSpscRingBufferclears each slot when it dequeues.Repro (reproduced)
Why it matters
Ring buffers usually hold recent large objects, such as frames, audio blocks or log entries. After
Clear(), a buffer of N slots can keep up to N of them in memory for as long as the buffer itself lives.Suggested fix
In
Clear(), clear the array before resetting the indices whenTcontains references:On netstandard targets, use
!typeof(T).IsValueType, as the other containers do.Acceptance: a WeakReference test shows that items are collectable after
Clear().