问题
I was using with ArrayPool in C#. I wanted to create my own pool with max no of arrays 5 and max size of array 1050000. I used this ArrayPool.Create() method. I am not able to understand one thing - i am trying to rent from the pool 10 times in the snippet below ,although i specified max arrays to be 5 , then why is it not showing any error. Also, i specified max length to be 1050000.Then how am i able to rent a 4200000 array without any error ?
byte[] buffer;
ArrayPool<byte> pool = ArrayPool<byte>.Create(1050000, 5);
for (int i = 0; i < 10; i++)
{
buffer = pool.Rent(4200000);
}
回答1:
The options passed to ArrayPool.Create
don't imply you cannot recieve an array larger than those limits. Instead they are used to control the bucketing algorithm of the ConfigurableArrayPool
. The second argument is the maximum number of slots in a bucket and the first is the maximum size of any array. This value is capped by an internal constant of 1,048,576
which is already smaller than your 1,050,000
.
When you Rent
from the array pool, the algorithm will attempt to locate an array in one of the buckets/slots. The number of these buckets (and their internal slots) are what become limited by the values you passed in. If the pool doesn't have an array of the minimum size requested either because all slots are in use or because the requested size is greater than the maximum, it will instead allocate a new one (without pooling it) and return that.
In short, when you request an array larger than the (capped) size you passed in to the Create
method you will incur an allocation and recieve an array that does not participate in the pool. Calling Return
with this array will not place it back into the pool; instead it will be "dropped".
Keep in mind however that these rules only apply to the built-in array pool. You (or someone else) could write an implementation that caps the size of the returned array or even throws -- though I'd argue that those might not be considered well-behaved (at least without supporting doc).
Update based on your comments:
While true there is not a parameter that corresponds directly to the number of buckets, there is indirectly. The number of buckets is calculated using the maximum array size you pass in. The max buckets is determined based on powers of 2 and some other logic.
回答2:
Documentation has no exceptions defined for the Rent
method (though there is at least one which can be thrown - ArgumentOutOfRangeException
for negative array sizes).
Looking at the source code for the Create
method - it returns ConfigurableArrayPool. It's Rent
method will try to find an array matching for the request and if there is no suitable one it will just allocate a new one:
// The request was for a size too large for the pool. Allocate an array of exactly the requested length.
// When it's returned to the pool, we'll simply throw it away.
buffer = new T[minimumLength];
So both parameters (maxArrayLength
and maxArraysPerBucket
) are used just to control what ArrayPool
will actually store and reuse, not how much can be allocated (and it makes sense, usually you don't want your application to fail while allocating memory if there is enough of memory available to it). Everything else will be in the control of GC
, so ArrayPool
will not end up storing a lot of noncollectable memory.
来源:https://stackoverflow.com/questions/62584548/arraypool-create-method-in-c-sharp