Array größer als 2Gb (Int32.Max) - gcAllowVeryLargeObjects

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Facebamm.

    Array größer als 2Gb (Int32.Max) - gcAllowVeryLargeObjects

    Hallo :D

    Ich bin gerade dabei eine Datenbank auszulesen.

    In dieser sind mehr als Int32.Max Tupel enthalten die ich einmal Komplett reinladen müsste in ein Array.
    Ich weiß es gibt limits womit ich ein Teil der Tupel laden könnte und dann den Rest, aber die Tupel basieren aufeinfander und müssen im Ganzen gesehen werden.

    Was ich im Internet gefunden habe ist - gcAllowVeryLargeObjects - aber ich hab keine Ahnung wie die Eigenschaft in dotnet Core setze O.o

    Kann mir da wer helfen? ?(

    EDIT:
    Source - Code
    Spoiler anzeigen

    C#-Quellcode

    1. ​unsafe class BigList<T> : IDisposable
    2. {
    3. private const int BASE_INIT_CAP = 4;
    4. private delegate IntPtr InternalAllocDelegate(object obj, GCHandleType gCHandleType);
    5. private delegate void InternalFreeDelegate(IntPtr handle);
    6. private delegate object InternalGetDelegate(IntPtr handle);
    7. private static readonly InternalAllocDelegate InternalAlloc = GetMethodOf<InternalAllocDelegate>(typeof(GCHandle), "InternalAlloc", BindingFlags.NonPublic | BindingFlags.Static);
    8. private static readonly InternalFreeDelegate InternalFree = GetMethodOf<InternalFreeDelegate>(typeof(GCHandle), "InternalFree", BindingFlags.NonPublic | BindingFlags.Static);
    9. private static readonly InternalGetDelegate InternalGet = GetMethodOf<InternalGetDelegate>(typeof(GCHandle), "InternalGet", BindingFlags.NonPublic | BindingFlags.Static);
    10. public T this[long index] {
    11. get => (T)InternalGet(GetHandleValue(ref *((IntPtr*)_internalMem.ToPointer() + index)));
    12. set {
    13. IntPtr* elementPtr = ((IntPtr*)_internalMem.ToPointer() + index);
    14. if (*elementPtr != IntPtr.Zero)
    15. {
    16. InternalFree(*elementPtr);
    17. }
    18. *elementPtr = SetIsPinned(InternalAlloc(value, GCHandleType.Pinned));
    19. }
    20. }
    21. private long _capacity;
    22. private IntPtr _internalMem;
    23. public long Count;
    24. public BigList() : this(BASE_INIT_CAP) { }
    25. public BigList(long baseCapacity)
    26. {
    27. _capacity = baseCapacity * IntPtr.Size;
    28. _internalMem = Marshal.AllocHGlobal(new IntPtr(_capacity));
    29. Count = 0;
    30. }
    31. public long AddItems(T element)
    32. {
    33. if (Count * IntPtr.Size == _capacity)
    34. {
    35. _capacity *= 2;
    36. IntPtr memAlloc = Marshal.AllocHGlobal(new IntPtr(_capacity));
    37. Buffer.MemoryCopy(_internalMem.ToPointer(), memAlloc.ToPointer(), _capacity, Count * IntPtr.Size);
    38. Marshal.FreeHGlobal(_internalMem);
    39. _internalMem = memAlloc;
    40. }
    41. *(((IntPtr*)_internalMem) + Count) = SetIsPinned(InternalAlloc(element, GCHandleType.Pinned));
    42. return Count++;
    43. }
    44. internal IntPtr GetHandleValue(ref IntPtr handle)
    45. {
    46. #if WIN32
    47. return new IntPtr(((int)handle) & ~1);
    48. #else
    49. return new IntPtr(((long)handle) & ~1L);
    50. #endif
    51. }
    52. internal bool IsPinned(ref IntPtr handle)
    53. {
    54. #if WIN32
    55. return (((int)handle) & 1) != 0;
    56. #else
    57. return (((long)handle) & 1) != 0;
    58. #endif
    59. }
    60. internal IntPtr SetIsPinned(IntPtr handle)
    61. {
    62. #if WIN32
    63. return new IntPtr(((int)handle) | 1);
    64. #else
    65. return new IntPtr(((long)handle) | 1L);
    66. #endif
    67. }
    68. ~BigList()
    69. {
    70. Dispose(false);
    71. }
    72. bool isDisposed;
    73. public void Dispose(bool dispose)
    74. {
    75. if (!isDisposed)
    76. {
    77. isDisposed = true;
    78. if (dispose)
    79. {
    80. for (int iElement = 0; iElement < Count; iElement++)
    81. {
    82. InternalFree(GetHandleValue(ref *((IntPtr*)_internalMem + iElement)));
    83. }
    84. }
    85. Marshal.FreeHGlobal(_internalMem);
    86. }
    87. }
    88. public void Dispose()
    89. {
    90. Dispose(true);
    91. GC.SuppressFinalize(this);
    92. }
    93. private static TOut GetMethodOf<TOut>(Type type, string methodeName, BindingFlags bindingFlags) where TOut : Delegate
    94. => (TOut)Delegate.CreateDelegate(typeof(TOut), type.GetMethod(methodeName, bindingFlags));
    95. }



    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Facebamm“ ()

    Und ne List(Of T) geht hier nicht? Keine Ahnung was hier die Max Kapazität ist.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @mrMo Eine Liste ist intern auch nur ein Array.

    Was heißt denn aufeinander basieren? So viel Zeugs in den Arbeitsspeicher zu laden ist sicher keine gute Idee. Vielleicht sollte man bei der Datenbank schon ansetzen und da passende Daten rausfiltern?

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    gcAllowVeryLargeObjects bringt dir an dieser Stelle vermutlich nichts. Es erhöht nicht die Anzahl der Objekte für ein Array, sondern nur die Größe des Speicherblocks, also wie groß ein einzelnes Objekt (Bytes) innerhalb des Arrays sein kann. Wenn du mehr als Int32.Max Elemente haben möchtest, kannst du das mit Marshal.AllocHGlobal(new IntPtr(24_000_000_000 /*Beispiel*/)) erreichen. Damit kannst du dir selber z.B. 24GB allozieren und dann über Pointer darauf zugreifen. Ich würde mir an deiner Stelle dafür dann eine Klasse als Wrapper schreiben, die wie ein Array oder Liste aufgebaut ist.
    Für andere User falls diese mal auf das geiche Problem stoßen


    !! Ihr dürft keine Class drauß machen !!
    Edit: Old - schau oben
    Spoiler anzeigen

    C#-Quellcode

    1. unsafe struct BigList<T> : IDisposable
    2. {
    3. private const int BASE_INIT_CAP = 4;
    4. private delegate IntPtr InternalAllocDelegate(object obj, GCHandleType gCHandleType);
    5. private delegate void InternalFreeDelegate(IntPtr handle);
    6. private delegate object InternalGetDelegate(IntPtr handle);
    7. private static readonly InternalAllocDelegate InternalAlloc = GetMethodOf<InternalAllocDelegate>(typeof(GCHandle), "InternalAlloc", BindingFlags.NonPublic | BindingFlags.Static);
    8. private static readonly InternalFreeDelegate InternalFree = GetMethodOf<InternalFreeDelegate>(typeof(GCHandle), "InternalFree", BindingFlags.NonPublic | BindingFlags.Static);
    9. private static readonly InternalGetDelegate InternalGet = GetMethodOf<InternalGetDelegate>(typeof(GCHandle), "InternalGet", BindingFlags.NonPublic | BindingFlags.Static);
    10. public T this[long index] {
    11. get => (T)InternalGet(*((IntPtr*)_internalMem.ToPointer() + index));
    12. set {
    13. IntPtr* elementPtr = ((IntPtr*)_internalMem.ToPointer() + index);
    14. if (*elementPtr != IntPtr.Zero)
    15. {
    16. InternalFree(*elementPtr);
    17. }
    18. *elementPtr = InternalAlloc(value, GCHandleType.Pinned);
    19. }
    20. }
    21. private long _capacity;
    22. private IntPtr _internalMem;
    23. public long Count;
    24. //public BigList() : this(BASE_INIT_CAP) { }
    25. public BigList(long baseCapacity)
    26. {
    27. _capacity = baseCapacity * IntPtr.Size;
    28. _internalMem = Marshal.AllocHGlobal(new IntPtr(_capacity));
    29. Count = 0;
    30. }
    31. public long AddItems(T element)
    32. {
    33. if (Count * IntPtr.Size == _capacity)
    34. {
    35. _capacity *= 2;
    36. IntPtr memAlloc = Marshal.AllocHGlobal(new IntPtr(_capacity));
    37. Buffer.MemoryCopy(_internalMem.ToPointer(), memAlloc.ToPointer(), _capacity, Count * IntPtr.Size);
    38. Marshal.FreeHGlobal(_internalMem);
    39. _internalMem = memAlloc;
    40. }
    41. *(((IntPtr*)_internalMem.ToPointer()) + Count) = InternalAlloc(element, GCHandleType.Pinned);
    42. return Count++;
    43. }
    44. public void Dispose()
    45. {
    46. for (int iElement = 0; iElement < Count; iElement++)
    47. {
    48. InternalFree(*((IntPtr*)_internalMem + Count));
    49. }
    50. Marshal.FreeHGlobal(_internalMem);
    51. }
    52. private static TOut GetMethodOf<TOut>(Type type, string methodeName, BindingFlags bindingFlags) where TOut : Delegate
    53. => (TOut)Delegate.CreateDelegate(typeof(TOut), type.GetMethod(methodeName, bindingFlags));
    54. }

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Facebamm“ ()