Last active
September 12, 2024 19:17
-
-
Save OnurGumus/5b4b3de0364b6bfc104607cf34f01dc3 to your computer and use it in GitHub Desktop.
AutoReturnArrayPool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Buffers; | |
using System.Runtime.CompilerServices; | |
using System.Collections.Generic; | |
using System.Threading; | |
var allocatedArrays = new HashSet<int>(); // To track allocated arrays | |
int i = 0; | |
while (true) | |
{ | |
i++; | |
var array = AutoReturnArrayPool.Rent<int>(1000000); | |
int arrayId = RuntimeHelpers.GetHashCode(array); // Use RuntimeHelpers.GetHashCode() to get a stable hash code | |
// Log whether the array is new or reused | |
if (!allocatedArrays.Contains(arrayId)) | |
{ | |
Console.WriteLine($"New array allocated: {arrayId}"); | |
allocatedArrays.Add(arrayId); | |
} | |
else | |
{ | |
Console.WriteLine($"Reused array: {arrayId}"); | |
} | |
Console.WriteLine($"Total memory: {GC.GetTotalMemory(false)}"); | |
if (i % 30 == 0) | |
{ | |
// Force garbage collection to observe memory usage | |
GC.Collect(); | |
GC.WaitForPendingFinalizers(); | |
} | |
Thread.Sleep(1000); | |
} | |
public static class AutoReturnArrayPool | |
{ | |
// A table that attaches finalizers to rented arrays | |
private static readonly ConditionalWeakTable<Array, object> finalizers = new(); | |
public static T[] Rent<T>(int length) | |
{ | |
var pool = ArrayPool<T>.Shared; | |
var array = pool.Rent(length); | |
// Check if the array is already in the table, if not, add it | |
if (!finalizers.TryGetValue(array, out _)) | |
{ | |
finalizers.Add(array, new Finalizer<T>(array)); | |
} | |
return array; | |
} | |
public static void Return<T>(T[] array) | |
{ | |
var pool = ArrayPool<T>.Shared; | |
Console.WriteLine("Returned"); | |
pool.Return(array); | |
finalizers.Remove(array); // Optionally, remove from the ConditionalWeakTable to avoid memory leaks | |
} | |
private class Finalizer<T> | |
{ | |
private readonly T[] array; | |
public Finalizer(T[] array) | |
{ | |
this.array = array; | |
} | |
~Finalizer() | |
{ | |
// This will be called when the array is collected | |
AutoReturnArrayPool.Return(array); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment