static void RunTest() { var trimSettings1 = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 6_000 }; var pool1 = new UniformUnmanagedMemoryPool(128, 256, trimSettings1); Thread.Sleep(8_000); // Let some callbacks fire already var trimSettings2 = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 3_000 }; var pool2 = new UniformUnmanagedMemoryPool(128, 256, trimSettings2); pool1.Return(pool1.Rent(64)); pool2.Return(pool2.Rent(64)); Assert.Equal(128, UnmanagedMemoryHandle.TotalOutstandingHandles); // This exercises pool weak reference list trimming: LeakPoolInstance(); GC.Collect(); GC.WaitForPendingFinalizers(); Assert.Equal(128, UnmanagedMemoryHandle.TotalOutstandingHandles); Thread.Sleep(15_000); Assert.True( UnmanagedMemoryHandle.TotalOutstandingHandles <= 64, $"UnmanagedMemoryHandle.TotalOutstandingHandles={UnmanagedMemoryHandle.TotalOutstandingHandles} > 64"); GC.KeepAlive(pool1); GC.KeepAlive(pool2); }
public static bool TryAllocate( UniformUnmanagedMemoryPool pool, long totalLengthInElements, int bufferAlignmentInElements, AllocationOptions options, out MemoryGroup <T> memoryGroup) { Guard.NotNull(pool, nameof(pool)); Guard.MustBeGreaterThanOrEqualTo(totalLengthInElements, 0, nameof(totalLengthInElements)); Guard.MustBeGreaterThanOrEqualTo(bufferAlignmentInElements, 0, nameof(bufferAlignmentInElements)); int blockCapacityInElements = pool.BufferLength / ElementSize; if (bufferAlignmentInElements > blockCapacityInElements) { memoryGroup = null; return(false); } if (totalLengthInElements == 0) { throw new InvalidMemoryOperationException("Allocating 0 length buffer from UniformByteArrayPool is disallowed"); } int numberOfAlignedSegments = blockCapacityInElements / bufferAlignmentInElements; int bufferLength = numberOfAlignedSegments * bufferAlignmentInElements; if (totalLengthInElements > 0 && totalLengthInElements < bufferLength) { bufferLength = (int)totalLengthInElements; } int sizeOfLastBuffer = (int)(totalLengthInElements % bufferLength); int bufferCount = (int)(totalLengthInElements / bufferLength); if (sizeOfLastBuffer == 0) { sizeOfLastBuffer = bufferLength; } else { bufferCount++; } UnmanagedMemoryHandle[] arrays = pool.Rent(bufferCount); if (arrays == null) { // Pool is full memoryGroup = null; return(false); } memoryGroup = new Owned(pool, arrays, bufferLength, totalLengthInElements, sizeOfLastBuffer, options); return(true); }
static void RunTest() { var trimSettings = new UniformUnmanagedMemoryPool.TrimSettings { TrimPeriodMilliseconds = 5_000 }; var pool = new UniformUnmanagedMemoryPool(128, 256, trimSettings); UnmanagedMemoryHandle[] a = pool.Rent(64); UnmanagedMemoryHandle[] b = pool.Rent(64); pool.Return(a); Assert.Equal(128, UnmanagedMemoryHandle.TotalOutstandingHandles); Thread.Sleep(15_000); // We expect at least 2 Trim actions, first trim 32, then 16 arrays. // 128 - 32 - 16 = 80 Assert.True( UnmanagedMemoryHandle.TotalOutstandingHandles <= 80, $"UnmanagedMemoryHandle.TotalOutstandingHandles={UnmanagedMemoryHandle.TotalOutstandingHandles} > 80"); pool.Return(b); }