ArrayPool.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. namespace System.Buffers
  5. {
  6. /// <summary>
  7. /// Provides a resource pool that enables reusing instances of type <see cref="T:T[]"/>.
  8. /// </summary>
  9. /// <remarks>
  10. /// <para>
  11. /// Renting and returning buffers with an <see cref="ArrayPool{T}"/> can increase performance
  12. /// in situations where arrays are created and destroyed frequently, resulting in significant
  13. /// memory pressure on the garbage collector.
  14. /// </para>
  15. /// <para>
  16. /// This class is thread-safe. All members may be used by multiple threads concurrently.
  17. /// </para>
  18. /// </remarks>
  19. public abstract class ArrayPool<T>
  20. {
  21. // Store the shared ArrayPool in a field of its derived sealed type so the Jit can "see" the exact type
  22. // when the Shared property is inlined which will allow it to devirtualize calls made on it.
  23. private readonly static TlsOverPerCoreLockedStacksArrayPool<T> s_shared = new TlsOverPerCoreLockedStacksArrayPool<T>();
  24. /// <summary>
  25. /// Retrieves a shared <see cref="ArrayPool{T}"/> instance.
  26. /// </summary>
  27. /// <remarks>
  28. /// The shared pool provides a default implementation of <see cref="ArrayPool{T}"/>
  29. /// that's intended for general applicability. It maintains arrays of multiple sizes, and
  30. /// may hand back a larger array than was actually requested, but will never hand back a smaller
  31. /// array than was requested. Renting a buffer from it with <see cref="Rent"/> will result in an
  32. /// existing buffer being taken from the pool if an appropriate buffer is available or in a new
  33. /// buffer being allocated if one is not available.
  34. /// byte[] and char[] are the most commonly pooled array types. For these we use a special pool type
  35. /// optimized for very fast access speeds, at the expense of more memory consumption.
  36. /// The shared pool instance is created lazily on first access.
  37. /// </remarks>
  38. public static ArrayPool<T> Shared => s_shared;
  39. /// <summary>
  40. /// Creates a new <see cref="ArrayPool{T}"/> instance using default configuration options.
  41. /// </summary>
  42. /// <returns>A new <see cref="ArrayPool{T}"/> instance.</returns>
  43. public static ArrayPool<T> Create() => new ConfigurableArrayPool<T>();
  44. /// <summary>
  45. /// Creates a new <see cref="ArrayPool{T}"/> instance using custom configuration options.
  46. /// </summary>
  47. /// <param name="maxArrayLength">The maximum length of array instances that may be stored in the pool.</param>
  48. /// <param name="maxArraysPerBucket">
  49. /// The maximum number of array instances that may be stored in each bucket in the pool. The pool
  50. /// groups arrays of similar lengths into buckets for faster access.
  51. /// </param>
  52. /// <returns>A new <see cref="ArrayPool{T}"/> instance with the specified configuration options.</returns>
  53. /// <remarks>
  54. /// The created pool will group arrays into buckets, with no more than <paramref name="maxArraysPerBucket"/>
  55. /// in each bucket and with those arrays not exceeding <paramref name="maxArrayLength"/> in length.
  56. /// </remarks>
  57. public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket) =>
  58. new ConfigurableArrayPool<T>(maxArrayLength, maxArraysPerBucket);
  59. /// <summary>
  60. /// Retrieves a buffer that is at least the requested length.
  61. /// </summary>
  62. /// <param name="minimumLength">The minimum length of the array needed.</param>
  63. /// <returns>
  64. /// An <see cref="T:T[]"/> that is at least <paramref name="minimumLength"/> in length.
  65. /// </returns>
  66. /// <remarks>
  67. /// This buffer is loaned to the caller and should be returned to the same pool via
  68. /// <see cref="Return"/> so that it may be reused in subsequent usage of <see cref="Rent"/>.
  69. /// It is not a fatal error to not return a rented buffer, but failure to do so may lead to
  70. /// decreased application performance, as the pool may need to create a new buffer to replace
  71. /// the one lost.
  72. /// </remarks>
  73. public abstract T[] Rent(int minimumLength);
  74. /// <summary>
  75. /// Returns to the pool an array that was previously obtained via <see cref="Rent"/> on the same
  76. /// <see cref="ArrayPool{T}"/> instance.
  77. /// </summary>
  78. /// <param name="array">
  79. /// The buffer previously obtained from <see cref="Rent"/> to return to the pool.
  80. /// </param>
  81. /// <param name="clearArray">
  82. /// If <c>true</c> and if the pool will store the buffer to enable subsequent reuse, <see cref="Return"/>
  83. /// will clear <paramref name="array"/> of its contents so that a subsequent consumer via <see cref="Rent"/>
  84. /// will not see the previous consumer's content. If <c>false</c> or if the pool will release the buffer,
  85. /// the array's contents are left unchanged.
  86. /// </param>
  87. /// <remarks>
  88. /// Once a buffer has been returned to the pool, the caller gives up all ownership of the buffer
  89. /// and must not use it. The reference returned from a given call to <see cref="Rent"/> must only be
  90. /// returned via <see cref="Return"/> once. The default <see cref="ArrayPool{T}"/>
  91. /// may hold onto the returned buffer in order to rent it again, or it may release the returned buffer
  92. /// if it's determined that the pool already has enough buffers stored.
  93. /// </remarks>
  94. public abstract void Return(T[] array, bool clearArray = false);
  95. }
  96. }