我在.NET上固定一个对象并获得一个GCHandle。我想泄漏大部分这些GCHandle并忘记它们(所以这些对象继续被固定)。后来,我想解锁一些物体。那时我只有对象(或对象的地址)。我可以从对象获取固定对象的GCHandles吗?
看来每个GCHandle固定调用返回一个新的GCHandle。 GCHandle.ToIntPtr和GCHandle.FromIntPtr显示本地整数等于这些GCHandles。
是否有可能从一个对象或从AddrOfPinnedObject获取GCHandle?
我在.NET上固定一个对象并获得一个GCHandle。我想泄漏大部分这些GCHandle并忘记它们(所以这些对象继续被固定)。后来,我想解锁一些物体。那时我只有对象(或对象的地址)。我可以从对象获取固定对象的GCHandles吗?
看来每个GCHandle固定调用返回一个新的GCHandle。 GCHandle.ToIntPtr和GCHandle.FromIntPtr显示本地整数等于这些GCHandles。
是否有可能从一个对象或从AddrOfPinnedObject获取GCHandle?
不,一旦你失去了GCHandle,那么你就永远失去了它。在垃圾回收器中没有'处理句柄'的概念。您只能为一个对象创建一个新的 GCHandle,它会添加一个额外的引用。这个丢失句柄引用的对象将被永久引用,这是一个泄漏。请注意,GCHandle是一个结构类型。
保持对象固定任何时间长度的想法都不利于您的程序的性能。由于给了GC更难以解决障碍的问题,它也阻止了它正确压缩堆。这增加了缓存未命中的可能性,在现代内核上非常昂贵。这些副作用可能会持续一段时间。
如果您需要固定内存,然后使用Marshal.AllocCoTaskMem()进行分配。这也会阻止您创建指向具有不可预知内存布局的托管数据的指针。不同版本的JIT编译器之间的布局有所不同,并且高度依赖于结构或类声明。只有Marshal.StructureToPtr()可以给你很大的保证。
Marshal.AllocCoTaskMem看起来相关。谢谢。 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.alloccotaskmem.aspx – James 2010-11-10 14:38:22
Marshal.AllocHGlobal在这里http://msdn.microsoft.com/en-us/library/ system.runtime.interopservices.marshal.allochglobal.aspx – James 2010-11-10 15:00:00
Hans有很好的建议http://stackoverflow.com/questions/1887288/marshal-allochglobal-vs-marshal-alloccotaskmem-marshal-sizeof-vs-sizeof/1887765#1887765 – James 2010-11-10 15:00:17
我正在寻找相同的解决方案。我有一个不再支持的第三方组件,它似乎是固定我们拥有的对象。我想强制该对象被释放,但没有对GCHandle的引用。如果您发现任何解决方案,请将其传递。 – jpierson 2011-11-16 18:33:59