NativeMemoryHelper.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. namespace NativeCollection
  6. {
  7. public static unsafe class NativeMemoryHelper
  8. {
  9. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  10. public static void* Alloc(UIntPtr byteCount)
  11. {
  12. AddNativeMemoryByte((long)byteCount);
  13. #if NET6_0_OR_GREATER
  14. return NativeMemory.Alloc(byteCount);
  15. #else
  16. return Marshal.AllocHGlobal((int)byteCount).ToPointer();
  17. #endif
  18. }
  19. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  20. public static void* Alloc(UIntPtr elementCount, UIntPtr elementSize)
  21. {
  22. AddNativeMemoryByte((long)((long)elementCount * (long)elementSize));
  23. #if NET6_0_OR_GREATER
  24. return NativeMemory.Alloc(elementCount, elementSize);
  25. #else
  26. return Marshal.AllocHGlobal((int)((int)elementCount*(int)elementSize)).ToPointer();
  27. #endif
  28. }
  29. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  30. public static void* AllocZeroed(UIntPtr byteCount)
  31. {
  32. AddNativeMemoryByte((long)byteCount);
  33. #if NET6_0_OR_GREATER
  34. return NativeMemory.AllocZeroed(byteCount);
  35. #else
  36. var ptr = Marshal.AllocHGlobal((int)byteCount).ToPointer();
  37. Unsafe.InitBlockUnaligned(ptr,0,(uint)byteCount);
  38. return ptr;
  39. #endif
  40. }
  41. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  42. public static void* AllocZeroed(UIntPtr elementCount, UIntPtr elementSize)
  43. {
  44. AddNativeMemoryByte((long)((long)elementCount * (long)elementSize));
  45. #if NET6_0_OR_GREATER
  46. return NativeMemory.AllocZeroed(elementCount, elementSize);
  47. #else
  48. var ptr = Marshal.AllocHGlobal((int)((int)elementCount*(int)elementSize)).ToPointer();
  49. Unsafe.InitBlockUnaligned(ptr,0,(uint)((uint)elementCount*(uint)elementSize));
  50. return ptr;
  51. #endif
  52. }
  53. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  54. public static void Free<T>(T* ptr) where T : unmanaged
  55. {
  56. #if NET6_0_OR_GREATER
  57. NativeMemory.Free(ptr);
  58. #else
  59. Marshal.FreeHGlobal(new IntPtr(ptr));
  60. #endif
  61. }
  62. #if MEMORY_PROFILE
  63. public static long NativeMemoryBytes;
  64. #endif
  65. public static void AddNativeMemoryByte(long size)
  66. {
  67. GC.AddMemoryPressure((long)size);
  68. //Console.WriteLine($"AddNativeMemoryByte {size}");
  69. #if MEMORY_PROFILE
  70. NativeMemoryBytes += size;
  71. #endif
  72. }
  73. public static void RemoveNativeMemoryByte(long size)
  74. {
  75. GC.RemoveMemoryPressure(size);
  76. //Console.WriteLine($"RemoveMemoryPressure {size}");
  77. #if MEMORY_PROFILE
  78. NativeMemoryBytes -= size;
  79. #endif
  80. }
  81. public static long GetNativeMemoryBytes()
  82. {
  83. #if MEMORY_PROFILE
  84. return NativeMemoryBytes;
  85. #else
  86. return 0;
  87. #endif
  88. }
  89. }
  90. }