我在.NET上固定一个对象并得到一个GCHandle。我想泄漏大部分这些GCHandle而忘记它们(所以对象继续固定)。后来,对于一些我想解开它们的对象。那时我只有对象(或对象的地址)。
似乎每个GCHandle固定呼叫都返回一个新的GCHandle。 GCHandle.ToIntPtr和GCHandle.FromIntPtr显示本机整数等同于这些GCHandles。
是否可以从对象或AddrOfPinnedObject获取GCHandle?
答案 0 :(得分:3)
不,一旦你失去GCHandle,你就会永远失去它。垃圾收集器中没有“手柄处理”的概念。您只能为对象创建 new GCHandle,它将添加额外的引用。这个丢失句柄引用的对象将被永久引用,这是一个泄漏。请注意,GCHandle是一种结构类型。
保持对象固定任何时间长度的想法对你的程序的性能是不利的。如果不让GC更难以绕过障碍物,它还可以防止它正确地压缩堆。这增加了缓存未命中的可能性,在现代核心上非常昂贵。这些副作用可能会持续一段时间。
如果您需要固定内存,请使用Marshal.AllocCoTaskMem()进行分配。这也会阻止您创建指向具有不可预测的内存布局的托管数据的指针。不同版本的JIT编译器之间的布局不同,并且高度依赖于struct或class声明。只有Marshal.StructureToPtr()可以给你很大的保证。
答案 1 :(得分:0)
对于那些您需要免费的人,请保留GCHandles并使用Free
。 GCHandle知道对象,而不是相反。
另外,想要保持固定对象并不好。我希望您意识到您将阻止GC正常工作。