2010-03-04 33 views
1

我想跟蹤使用ANTS分析器的應用程序中的內存泄漏。我將其追蹤到垃圾收集器,在那裏我們有一個對象列表System.Transactions.SafeIUnknown,它們永遠坐在垃圾收集器中,處於終結器隊列中,但永遠不會被釋放。在.NET垃圾收集器與System.Transactions.SafeIUnknown內存泄漏

我可以在System.Transactions.SafeIUnknown找到不記錄什麼,也不能確定將會創建或引用它的內容,這對我們來說沒有任何意圖。

我希望有人對此有所瞭解。這是一個20字節的小漏洞,但是當我們的應用程序運行數天後,漏洞就會增加,我們有數百萬次這樣的等待結束,並且它開始吃掉很多很多的內存。

任何想法何去何從?

後續

我跟蹤它到正在使用某個庫。在我們通過這個特定的庫執行任何SQL語句之後,它似乎被留下了。 statemtements沒有包含在事務中,但是它們通過一個相當複雜的循環,泛型類型來執行,目前看起來像雙向間接方式,代表被傳遞給運動並封裝在可以封裝更多閉包的閉包中。 我會繼續嘗試將其嚴格控制下來,我的第一個停靠點是嘗試使用類似的機制來重現它。

回答

1

SafeIUnknown來源於System.Transactions中的幾個方法,其中之一是TransactionScope構造函數和Dispose方法。調用這些結果的內部方法在名爲JitSafeGetContextTransactionTransaction類中,該類調用進一步調用本地Ole32函數CoGetDefaultContext,該函數返回SafeIUnknown的實例。

這提示所討論的對象與事務上下文的內部表示形式相關。

難道你沒有正確地釋放交易或交易範圍嗎?如果是這樣,那麼您使用的數據提供者可能存在一些問題?

+0

非常感謝以前評論中提到的評論彼得,我會繼續調查,看看我可以去的地方。 – Bigtoe 2010-03-04 16:09:27

+0

順便說一句,它是我使用的MS SQL數據提供程序。 – Bigtoe 2010-03-04 16:10:02

4

SafeIUnknown來自SafeHandle。這是實現終結器的類。它是特殊的,它的終結代碼運行在關鍵執行區域(CER)。這種代碼提供執行保證,異常被抑制。終結器運行SafeIUnknown.ReleaseHandle(),它調用Marshal.Release()釋放由SafeIUnknown包裝的COM接口指針。

在最終化隊列中看到很多這些包裝表明Marshal.Release()調用正在拋出異常。防止包裝完成。準確地找出它拋出異常的原因將會非常棘手。這是不受管理的代碼轟炸,你將有幾個提示可以找出原因。 95%的情況是堆損壞,這是一個非常難以解決的問題。最重要的是,因爲這可能不是你的代碼,你沒有任何來源。

您應該能夠在一次良好的非託管代碼調試器(如WinDbug)上獲得一次斷點。獲取調試符號對於理解堆棧跟蹤至關重要。然而,從那裏開始,它可能仍然是一個遠射。考慮從Microsoft支持獲取幫助。或者像重建機器那樣劇烈。祝你好運!

+0

感謝一堆評論。將繼續調查,看看我可以到達的地方。 – Bigtoe 2010-03-04 16:08:40