【问题标题】:How is the memory unpinned in Memory<T>.Span?Memory<T>.Span 中的内存是如何取消固定的?
【发布时间】:2019-08-04 17:35:13
【问题描述】:

我认为以下两段代码应该是等价的:

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

我不明白的是第二个示例中的内存取消固定在哪里。

据我了解,字符串是在堆上分配的,MemoryHandle 固定它并从指针创建 Span。 MemoryHandle.Dispose 取消固定内存。

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

【问题讨论】:

    标签: c# memory-management heap-memory


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      Span 只存在于当前方法线程的堆栈上,而不存在于它的堆上,因此只要您在那里使用它,它就会一直存在。到目前为止很清楚。

      现在有趣的部分:

      明确的事实是 memory.Span 的结果不是固定的,而是仅通过在 Span&lt;T&gt; 中使用 ref T 引用的,这是 GarbageCollector 也观察到的托管指针的 .net 理念。

      只要你的记忆还活着,你的跨度也会随之而变。

      参考资料:

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 2018-12-24
        • 1970-01-01
        • 2018-06-13
        • 1970-01-01
        • 2019-12-12
        • 1970-01-01
        相关资源
        最近更新 更多