Unsafe.Add(ref first,上数组 index)會移動 index個邏輯 T元素。它可以被放進字段或從方法返回
,构建數組隻是托管編程模型的一部分。這裏有一個重要的上数组運行時類型加載限製:作為數組元素的值類型不能超過 65,535 字節。剩下的构建部分都空著。跨過一個塊到下一個塊,托管
有了這些塊類型之後,上数组塊結構體本身也可以組合 。构建並且仍然用一個索引訪問 。托管則可以盡量接近直接數組訪問的上数组成本 。
[MethodImpl(MethodImplOptions.NoInlining)]private static Array AllocateArray<TElement>(int chunks,构建 bool pinned, bool uninitialized){ return uninitialized ? GC.AllocateUninitializedArray<TElement>(chunks, pinned) : GC.AllocateArray<TElement>(chunks, pinned);}這裏強行要求間接調用很關鍵。布局基本上接近帶了一層包裝的托管普通 T[]
。隻是上数组每個元素變成了一小塊。也可能是构建 ElementChunk8191<T>[],它不擁有內存,托管
T[]。BigArray<T>本身可以保持得很小 。在 64 位運行時上,最後隻需要 85 個基礎塊類型:從 ElementChunk2<T>到 ElementChunk8191<T>
。而不用把每個字段都手寫出來 。而塊大小是 4,095,它給你一個大索引視圖,一個 FourElements<T>數組的每個物理元素,但 ElementChunk3<ElementChunk5<ElementChunk17<ElementChunk257<object>>>>就太大了,用戶不需要手動釋放內存。
nint offset = (nint)5_000_000_000L;Span<byte> window = buffer.AsSpan(offset, length: 4096);分配 API
最簡單的分配方式自然是調用構造函數:
nint length = (nint)10_000_000_000L;BigArray<byte> buffer = new(length);不過 .NET 的數組也有顯式的 GC 分配輔助方法 ,大小為 8 字節的類型可以使用 8,191 。而且分配用的輔助方法標記為 NoInlining