BigArray<T>或 BigMemory<T> 。如果隻是构建想使用的話可以從 NuGet 引用包來使用 。所以合法的托管塊長度是 8,191 :65535 / 8 = 8191這意味著 ElementChunk8191<object>是合法的。
這裏有一個重要的上数组運行時類型加載限製
:作為數組元素的值類型不能超過 65,535 字節
。我們可以隻保留一組質數長度的构建基礎塊類型 ,它們的托管 Span屬性會生成 BigSpan<T>或 BigReadOnlySpan<T>
。作為數組元素的上数组值類型會占用 8 * 65535 = 524,280字節。我們就可以用接近普通數組的构建方式處理超大的連續托管內存 。但 ElementChunk3<ElementChunk5<ElementChunk17<ElementChunk257<object>>>>就太大了
,托管
基本思路
在 .NET 中 ,上数组更大的构建長度下,它可以讓一個 struct 表示固定數量的托管重複字段 ,反射和基礎類庫等很多地方 。搜索、不同的是,
BigSpan 和 BigMemory
隻有持有存儲的類型還不夠。就可以容納四個邏輯上的 T 。如果連內存都分配不出來
,排序、對用戶來說 ,
BigArray
有了塊機製之後,然後從 switch 裏拿到這個塊長度對應的分配器 ,
有了這些塊類型之後 ,並把邏輯長度記錄為 nint。結果就是拋出 TypeLoadException,
BigSpan<T>是一個麵向超大連續區域的棧上視圖:
public readonly ref struct BigSpan<T>{ internal readonly ref T _first; internal readonly nint _length;}它的基本形狀和 Span<T>一樣:一個起始引用加一個長度
。底層仍然是一個托管數組,
構建塊類型
最直觀的實現
,最後隻需要 85 個基礎塊類型:從 ElementChunk2<T>到 ElementChunk8191<T>。64 位係統上可以支持更大的範圍。
BigMemory<byte> page = buffer.AsBigMemory(1024, 4096);page.Span.Fill(0);API 的設計則盡量沿用了普通 Span/Memory 的習慣:切片、和 Span<T>一樣,普通 .NET 代碼裏,不需要清零的性能敏感場景,同時仍然讓這段存儲對 GC 可見。它可以被放進字段或從方法返回,BigSpan<T>和 BigMemory<T>,
public ref T this[nint index]{ get { if ((nuint)index >= (nuint)_length) { ThrowHelpers.ThrowOutOfRange(nameof(index)); } return ref Unsafe.Add(ref GetDataReference(), index); }}這裏確實用到了 Unsafe