Memory<T>.Span中的内存是如何unpinned的?
How is the memory unpinned in Memory<T>.Span?
我认为下面两段代码应该是等价的:
// first example
string s = "Hello memmory";
ReadOnlyMemory<char> memory = s.AsMemory();
using (MemoryHandle pin = memory.Pin())
{
Span<char> span = new Span<char>(pin.Pointer, 1);
Console.WriteLine(span[0]);
}
// second example
ReadOnlySpan<char> span2 = memory.Span;
Console.WriteLine(span2[0]);
两个代码都将打印 "H"。
我不明白的是第二个例子中内存的unpinning在哪里
据我所知,字符串是在堆上分配的,MemoryHandle
固定它并从指针创建 Span。 MemoryHandle.Dispose
取消固定内存。
我相信 memory.Span
也必须固定内存,否则 span 无法访问指针。但是第二个例子中的内存是如何解绑的呢?
Span 只存在于当前方法线程的栈上,而不存在于它的堆上,因此只要你在那里使用它,它就会存在。到目前为止很清楚。
现在是有趣的部分:
明确的事实是 memory.Span
的结果不是固定的,而是仅通过使用 Span<T>
中的 ref T
引用的由 GarbageCollector 观察到。
只要你的记忆还在,你的跨度也会存在,这就是你的跨度。
参考文献:
https://msdn.microsoft.com/en-us/magazine/mt814808.aspx?f=255&MSPPError=-2147217396
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref#ref-struct-types
最后一个假设是不正确的:memory.Span
不需要固定内存,因为垃圾收集器知道它的底层引用。如果您想将指针传递给本机 API.
,固定是独立可用的
我认为下面两段代码应该是等价的:
// first example
string s = "Hello memmory";
ReadOnlyMemory<char> memory = s.AsMemory();
using (MemoryHandle pin = memory.Pin())
{
Span<char> span = new Span<char>(pin.Pointer, 1);
Console.WriteLine(span[0]);
}
// second example
ReadOnlySpan<char> span2 = memory.Span;
Console.WriteLine(span2[0]);
两个代码都将打印 "H"。
我不明白的是第二个例子中内存的unpinning在哪里
据我所知,字符串是在堆上分配的,MemoryHandle
固定它并从指针创建 Span。 MemoryHandle.Dispose
取消固定内存。
我相信 memory.Span
也必须固定内存,否则 span 无法访问指针。但是第二个例子中的内存是如何解绑的呢?
Span 只存在于当前方法线程的栈上,而不存在于它的堆上,因此只要你在那里使用它,它就会存在。到目前为止很清楚。
现在是有趣的部分:
明确的事实是 memory.Span
的结果不是固定的,而是仅通过使用 Span<T>
中的 ref T
引用的由 GarbageCollector 观察到。
只要你的记忆还在,你的跨度也会存在,这就是你的跨度。
参考文献:
https://msdn.microsoft.com/en-us/magazine/mt814808.aspx?f=255&MSPPError=-2147217396 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref#ref-struct-types
最后一个假设是不正确的:memory.Span
不需要固定内存,因为垃圾收集器知道它的底层引用。如果您想将指针传递给本机 API.