in src/RecyclableMemoryStreamManager.cs [520:561]
internal void ReturnLargeBuffer(byte[] buffer, Guid id, string tag)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
if (!this.IsLargeBufferSize(buffer.Length))
{
throw new ArgumentException($"{nameof(buffer)} did not originate from this memory manager. The size is not " +
$"{(this.UseExponentialLargeBuffer ? "an exponential" : "a multiple")} of {this.LargeBufferMultiple}.");
}
var poolIndex = this.GetPoolIndex(buffer.Length);
if (poolIndex < this.largePools.Length)
{
if ((this.largePools[poolIndex].Count + 1) * buffer.Length <= this.MaximumFreeLargePoolBytes ||
this.MaximumFreeLargePoolBytes == 0)
{
this.largePools[poolIndex].Push(buffer);
Interlocked.Add(ref this.largeBufferFreeSize[poolIndex], buffer.Length);
}
else
{
ReportBufferDiscarded(id, tag, Events.MemoryStreamBufferType.Large, Events.MemoryStreamDiscardReason.EnoughFree);
}
}
else
{
// This is a non-poolable buffer, but we still want to track its size for inuse
// analysis. We have space in the inuse array for this.
poolIndex = this.largeBufferInUseSize.Length - 1;
ReportBufferDiscarded(id, tag, Events.MemoryStreamBufferType.Large, Events.MemoryStreamDiscardReason.TooLarge);
}
Interlocked.Add(ref this.largeBufferInUseSize[poolIndex], -buffer.Length);
ReportUsageReport(this.smallPoolInUseSize, this.smallPoolFreeSize, this.LargePoolInUseSize,
this.LargePoolFreeSize);
}