Refactor AllocationManager and enhance debug tracking
Refactored `AllocationManager` to introduce intrusive allocation tracking with `AllocationHeader` structs for debug mode. Added lightweight allocation counters for non-debug mode. Enhanced memory leak detection with detailed stack traces and `MemoryLeakException`. Simplified `AllocationInfo` by removing the `Allocator` property. Updated `AllocationOption` enum to remove `UnTracked` and clarified documentation. Improved unsafe collections (`UnsafeArray`, `UnsafeStack`, etc.) with strongly-typed enumerators and better compatibility with `IEnumerable<T>`. Enhanced `UnsafeStack` with a dedicated `Enumerator` struct and consistent constructor parameters. Refactored `MemoryLeakException` to support detailed allocation info and improved stack trace formatting. Simplified `MemoryUtility` by removing redundant null checks. Added unit tests for `AllocationManager`, `UnsafeArray`, and `UnsafeStack` to validate memory management and functionality. Updated `Program.cs` with new examples. Cleaned up namespaces, removed redundant `using` directives, and improved XML documentation. Applied `MethodImplOptions.AggressiveInlining` to performance-critical methods.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
using Misaki.HighPerformance.LowLevel;
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
|
||||
namespace Misaki.HighPerformance.Test.UnitTest.Buffer;
|
||||
|
||||
[TestClass]
|
||||
public class TestAllocationManager
|
||||
{
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
AllocationManager.EnableDebugLayer();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldNotLeakTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
var array = new UnsafeArray<int>(10, Allocator.Persistent);
|
||||
var array2 = new UnsafeArray<int>(10, Allocator.Persistent);
|
||||
|
||||
array.Dispose();
|
||||
array2.Dispose();
|
||||
|
||||
AllocationManager.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
var leaks = AllocationManager.LiveHeapAllocationCount;
|
||||
Assert.AreEqual(0, leaks);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ShouldLeakTest()
|
||||
{
|
||||
var array = new UnsafeArray<int>(10, Allocator.Persistent);
|
||||
var array2 = new UnsafeArray<int>(10, Allocator.Persistent);
|
||||
|
||||
try
|
||||
{
|
||||
AllocationManager.Dispose();
|
||||
}
|
||||
catch (MemoryLeakException)
|
||||
{
|
||||
var leaks = AllocationManager.LiveHeapAllocationCount;
|
||||
Assert.AreEqual(2, leaks);
|
||||
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
array.Dispose();
|
||||
array2.Dispose();
|
||||
}
|
||||
|
||||
Assert.Fail("Expected MemoryLeakException was not thrown.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
|
||||
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
|
||||
|
||||
[TestClass]
|
||||
public class TestUnsafeArray
|
||||
{
|
||||
private UnsafeArray<int> _arr;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_arr = new UnsafeArray<int>(16, Allocator.Persistent);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
_arr.Dispose();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestIndexAccess()
|
||||
{
|
||||
for (int i = 0; i < _arr.Count; i++)
|
||||
{
|
||||
_arr[i] = i * 10;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _arr.Count; i++)
|
||||
{
|
||||
Assert.AreEqual(i * 10, _arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestEnumeration()
|
||||
{
|
||||
_arr.Clear();
|
||||
|
||||
int expectedValue = 0;
|
||||
foreach (var item in _arr)
|
||||
{
|
||||
Assert.AreEqual(expectedValue, item);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestIsCreated()
|
||||
{
|
||||
Assert.IsTrue(_arr.IsCreated);
|
||||
_arr.Dispose();
|
||||
Assert.IsFalse(_arr.IsCreated);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Misaki.HighPerformance.Test.UnitTest.Collections;
|
||||
|
||||
[TestClass]
|
||||
public class TestUnsafeStack
|
||||
{
|
||||
private UnsafeStack<int> _stack;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
_stack = new UnsafeStack<int>(16, Allocator.Persistent);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
_stack.Dispose();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestPushPop()
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
_stack.Push(i);
|
||||
}
|
||||
Assert.AreEqual(10, _stack.Count);
|
||||
for (int i = 9; i >= 0; i--)
|
||||
{
|
||||
int value = _stack.Pop();
|
||||
Assert.AreEqual(i, value);
|
||||
}
|
||||
Assert.AreEqual(0, _stack.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestPeek()
|
||||
{
|
||||
_stack.Push(42);
|
||||
int value = _stack.Peek();
|
||||
Assert.AreEqual(42, value);
|
||||
Assert.AreEqual(1, _stack.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestEnumeration()
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
_stack.Push(i);
|
||||
}
|
||||
|
||||
int expected = 4;
|
||||
foreach (var item in _stack)
|
||||
{
|
||||
Assert.AreEqual(expected, item);
|
||||
expected--;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user