如何在内存中取消内存 。跨度?

问题描述 投票:1回答:2

我相信以下两段代码应该是等价的:

// 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”。

我不明白的是第二个例子中内存的取消。

据我所知,字符串在Heap上分配,MemoryHandle将其固定并从指针创建Span。 MemoryHandle.Dispose取消记忆回来。

我相信memory.Span也必须固定内存,否则span无法访问指针。但是在第二个例子中如何取消内存?

c# memory-management heap-memory
2个回答
1
投票

最后一个假设是不正确的:memory.Span不需要固定内存,因为垃圾收集器知道它的底层引用。如果您希望将指针传递给本机API,则可以单独使用固定。


0
投票

Span只存在于当前方法线程的堆栈上而不是它的堆上,因此只要你在那里使用它就会存活。到目前为止这么清楚。

现在有趣的部分:

明确的事实是memory.Span的结果并没有固定,而只是通过使用ref T中的Span<T>引用了什么是.nets关于管理指针的想法,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

© www.soinside.com 2019 - 2024. All rights reserved.