internal void DeAlloc(HeapPointers pointers) { if (pointers.isDead) { throw new MemoryException("Cannot deallocate already dead memory"); } pointers.isDead = true; pointers.VirtualOffset = 0; pointers.VirtualCount = 0; _pooledPointerArrays.Enqueue(pointers); }
internal HeapPointers AllocHeapPointers(uint size) { uint allocSize = Math.Max(minPointerArraySize, CalculateMultiple(size, pointerArraySizeMultiple)); bool pooled; if (!(pooled = _pooledPointerArrays.TryDequeue(out HeapPointers pointers))) { int createdHeapPointers = Interlocked.Increment(ref _createdPointerArrays); if (createdHeapPointers >= 1024 && !_hasWarnedAboutPointerArrayLeaks) { 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. [HEAP POINTERS]"); } _hasWarnedAboutPointerArrayLeaks = true; } pointers = new HeapPointers(allocSize); } pointers.EnsureSize(allocSize); pointers.IsDead = false; pointers.VirtualCount = size; pointers.VirtualOffset = 0; if (pooled) { // If we got one from the pool, we need to clear it Array.Clear(pointers.Pointers, 0, pointers.Pointers.Length); } #if RUFFLES_DEBUG // The allocation stacktrace allows us to see where the alloc occured that caused the leak pointers.allocStacktrace = new StackTrace(true); #endif return(pointers); }
internal void DeAlloc(HeapPointers pointers) { if (pointers.IsDead) { throw new MemoryException("Cannot deallocate already dead memory"); } pointers.VirtualOffset = 0; pointers.VirtualCount = 0; pointers.IsDead = true; if (!_pooledPointerArrays.TryEnqueue(pointers)) { // Failed to enqueue pointers. Queue is full if (Logging.CurrentLogLevel <= LogLevel.Warning) { Logging.LogWarning("Could not return heap pointers. The queue is full. The memory will be given to the garbage collector. [HEAP POINTERS]"); } } }