WeakHandle .NET Core 与 .NET Framework

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

在尝试 WeakHandles 时,我在 .NET 6 上发现了这个特性。

static void Main(string[] args) {
    var foo = new int[3];
    var fooWeakHandle = GCHandle.Alloc(foo, GCHandleType.Weak);
    GC.Collect();
    Console.WriteLine(fooWeakHandle.Target);
}

.NET 6 的结果(在发布模式下编译以避免急切的根收集)令人惊讶

System.Int32[]

在 .NET Framework 4.7.2 下,Release 中为 null/nothing,而 Debug 中为 System.Int32[]。 我使用 LinqPad (optimize+-) for Framework 和 .NET(Core) 得到了相同的结果。

为什么仅被 WeakHandle 引用的数组没有被垃圾回收?

c# garbage-collection weak-references
1个回答
0
投票

在.net框架中

foo
在最后一次使用后有资格收集。
 GCHandle.Alloc(foo, GCHandleType.Weak)
是最后一次使用,所以可以在
GC.Collect()
领取。

这在进行本机互操作时可能会导致问题,因为对象可能拥有本机资源,而 GC 无法知道这些资源是否被本机代码使用,这可能会导致过早处置资源。如果您没有意识到 GC 的这个怪癖,这可能会是相当意外的,但它可以通过 GC.KeepAlive 来修复。

此行为显然已在更高版本的 .net 版本中发生了变化。我不知道确切的原因,但我的猜测是错误的风险超过了收集性能的微小改进。

因此,这实际上并不是弱引用的变化,而是对象何时被视为可收集的变化。

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