2010-11-10 88 views
4

我在.NET上固定一個對象並獲得一個GCHandle。我想泄漏大部分這些GCHandle並忘記它們(所以這些對象繼續被固定)。後來,我想解鎖一些物體。那時我只有對象(或對象的地址)。我可以從對象獲取固定對象的GCHandles嗎?

看來每個GCHandle固定調用返回一個新的GCHandle。 GCHandle.ToIntPtr和GCHandle.FromIntPtr顯示本地整數等於這些GCHandles。

是否有可能從一個對象或從AddrOfPinnedObject獲取GCHandle?

+0

我正在尋找相同的解決方案。我有一個不再支持的第三方組件,它似乎是固定我們擁有的對象。我想強制該對象被釋放,但沒有對GCHandle的引用。如果您發現任何解決方案,請將其傳遞。 – jpierson 2011-11-16 18:33:59

回答

3

不,一旦你失去了GCHandle,那麼你就永遠失去了它。在垃圾回收器中沒有'處理句柄'的概念。您只能爲一個對象創建一個新的 GCHandle,它會添加一個額外的引用。這個丟失句柄引用的對象將被永久引用,這是一個泄漏。請注意,GCHandle是一個結構類型。

保持對象固定任何時間長度的想法都不利於您的程序的性能。由於給了GC更難以解決障礙的問題,它也阻止了它正確壓縮堆。這增加了緩存未命中的可能性,在現代內核上非常昂貴。這些副作用可能會持續一段時間。

如果您需要固定內存,然後使用Marshal.AllocCoTaskMem()進行分配。這也會阻止您創建指向具有不可預知內存佈局的託管數據的指針。不同版本的JIT編譯器之間的佈局有所不同,並且高度依賴於結構或類聲明。只有Marshal.StructureToPtr()可以給你很大的保證。

+0

Marshal.AllocCoTaskMem看起來相關。謝謝。 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.alloccotaskmem.aspx – James 2010-11-10 14:38:22

+0

Marshal.AllocHGlobal在這裏http://msdn.microsoft.com/en-us/library/ system.runtime.interopservices.marshal.allochglobal.aspx – James 2010-11-10 15:00:00

+0

Hans有很好的建議http://stackoverflow.com/questions/1887288/marshal-allochglobal-vs-marshal-alloccotaskmem-marshal-sizeof-vs-sizeof/1887765#1887765 – James 2010-11-10 15:00:17

0

對於那些你需要自由,保持GCHandles和使用Free。 GCHandle知道對象而不是其他方式。

此外,您想保留固定對象並不是很好。我希望你意識到你會阻止GC正常工作。

+0

好像我們需要維護ptr到GCHandle表以支持unp以響應ptr上的「free」。 – James 2010-11-10 14:06:29

+0

我意識到固定會修復堆中的對象。有沒有辦法確保他們在大型對象堆中? – James 2010-11-10 14:07:02

+0

使它們變大; 128kb應該做的,但谷歌它。爲什麼你需要固定大量的物體呢? – 2010-11-10 14:26:41

相關問題