我在 .NET 上固定一个对象并获得一个 GCHandle。我想泄漏大部分 GCHandle 并忘记它们(因此对象继续被固定)。后来,对于一些对象,我想取消固定它们。那时我只有对象(或对象的地址)。
似乎每个 GCHandle 固定调用都会返回一个新的 GCHandle。GCHandle.ToIntPtr 和 GCHandle.FromIntPtr 显示本机整数与这些 GCHandles 等效。
是否可以从对象或 AddrOfPinnedObject 获取 GCHandle(s)?
不,一旦你失去了 GCHandle,那么你就永远失去了它。垃圾收集器中没有“句柄到句柄”的概念。你只能为一个对象创建一个新的GCHandle,它会添加一个额外的引用。这个丢失的句柄引用的对象将被永久引用,这是一个泄漏。请注意,GCHandle 是一种结构类型。
保持对象固定任何时间长度的想法都会损害程序的性能。它不仅不会给 GC 带来更困难的时间来绕过障碍,还会阻止它正确压缩堆。这增加了缓存未命中的可能性,这对于现代内核来说非常昂贵。这些副作用可能会持续一段时间。
如果您需要固定内存,请使用 Marshal.AllocCoTaskMem() 分配它。这还可以阻止您创建指向具有不可预测的内存布局的托管数据的指针。不同版本的 JIT 编译器之间的布局有所不同,并且高度依赖于结构或类声明。只有 Marshal.StructureToPtr() 可以给你硬性保证。
| 归档时间: |
|
| 查看次数: |
1307 次 |
| 最近记录: |