我在.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