private MemoryWrapper AllocMemoryWrapper(HeapMemory allocatedMemory, ArraySegment <byte>?directMemory) { bool pooled; if (!(pooled = _pooledMemoryWrappers.TryDequeue(out MemoryWrapper wrapper))) { int createdMemoryWrappers = Interlocked.Increment(ref _createdMemoryWrappers); if (createdMemoryWrappers >= 1024 && !_hasWarnedAboutMemoryWrapperLeaks) { if (Logging.CurrentLogLevel <= LogLevel.Warning) { Logging.LogWarning("Memory leak suspected. Are you leaking memory to the GC or are your windows too large? Leaking memory to the GC will cause slowdowns. Make sure all memory is deallocated. [MEMORY WRAPPER]"); } _hasWarnedAboutMemoryWrapperLeaks = true; } wrapper = new MemoryWrapper(); } wrapper.IsDead = false; wrapper.AllocatedMemory = allocatedMemory; wrapper.DirectMemory = directMemory; #if RUFFLES_DEBUG // The allocation stacktrace allows us to see where the alloc occured that caused the leak wrapper.allocStacktrace = new StackTrace(true); #endif return(wrapper); }
internal void DeAlloc(MemoryWrapper wrapper) { if (wrapper.IsDead) { throw new MemoryException("Cannot deallocate already dead memory"); } wrapper.AllocatedMemory = null; wrapper.DirectMemory = null; wrapper.IsDead = true; if (!_pooledMemoryWrappers.TryEnqueue(wrapper)) { // Failed to enqueue pointers. Queue is full if (Logging.CurrentLogLevel <= LogLevel.Warning) { Logging.LogWarning("Could not return memory wrapper. The queue is full. The memory will be given to the garbage collector. [MEMORY WRAPPER]"); } } }