2010-11-16 29 views
3

我正在Compact .NET Framework v3.5下的Windows CE設備上使用基於事務的系統。我們發現,隨着越來越多的交易被執行,越來越少的內存可用。顯然是某種內存泄漏。在.NET Compact Framework中尋找內存泄漏(WinCE 5)

每次交易之後,我們會讀取兩條記憶讀數;一個來自OS(一個PInvoke調用),一個來自垃圾收集器。我們發現操作系統讀數正在增加內存使用量,而來自GC的讀數保持相對穩定(大約1MB差異+ - )。

該應用程序利用Microsoft Synchronization Services將信息存儲在幾個本地數據庫(SQL Server Compact v3.5)上,並將它們與遠程服務器進行同步。

如果這是Windows XP,我只需使用WinDbg連接到可執行文件,並分析堆以查看是否創建了永遠不會獲取GC的對象。但是,我甚至不知道託管堆是否是問題。

所以這個問題是兩個部分:

1)什麼是託管應用程序以這種方式泄漏內存(DataAdapters,流的罪魁,等)?

2)什麼調試工具/技術將幫助我追蹤確切的問題?

我知道這還不是很多,但現階段我沒有太多的信息。

謝謝!

回答

3

有兩種方法可以解決這個問題。首先是看管理對象及其生命週期。您可以使用Remote Performance Monitor(RPM)查看GC堆的快照並對其進行比較。

您可以使用CLR Profiler來檢查調用樹並查看這些對象來自何處。

這兩個工具通常會允許您查找託管代碼問題。

現在,重要的一點是你說GC沒有報告任何增長,這告訴我GC堆是好的,這些工具在這種特殊情況下不太可能找到。不過,我放棄了這些工具,因爲它們可能會在未來幫助您(或其他人閱讀此內容)。

就你而言,這聽起來像你有本地泄漏。你沒有說哪種類型的內存正在泄漏 - 物理的還是虛擬的 - 但幾乎可以肯定的是,有些內存正在使原本的分配無法獲得釋放。 SQL Compact是我基於你對你的體系結構的看法而推測出來的,因爲引擎是用本地代碼實現的,並且託管層位於其上。

我也猜測,根本原因是你有一些小的託管對象(可能是一個SqlCeTransaction或SqlCeCommand),它們分別有一個小的託管佔用空間,但是爲你做了一些本地分配,而這些對象是倖存。

託管工具應該允許您定位這些項目的數量很多或越來越多,並找到防止GC殺死它們的根目錄。驗證你正在調用Dispose所有你正在使用的SqlCe對象也是一件好事。

如果所有這些都找不到它,您可以潛入一些native tools,但它們在託管代碼方面表現不佳,並且不太可能給您提供太多信息。

+0

發現這個問題,並感謝您專注於SQL Compact,正如您所建議的。我們使用的強類型TableAdapter類在實例化時創建一個SqlCeConnection對象。這些連接永遠不會被我們關閉,也不會被自動生成的代碼關閉。 根據MSDN: 如果SqlCeConnection超出範圍,它不會關閉。您必須通過調用Close或Dispose來顯式關閉連接。 當我們單一實例化這些適配器的應用程序的生命週期時,問題大大減少了。還是有一些泄漏,但它可能是其他適配器 – CAP 2010-11-18 15:54:24

+0

......我們還沒有保護。 – CAP 2010-11-18 16:00:17

+0

是的,這仍然是爲什麼我們從不使用自動生成的強類型類的原因。主要原因是他們資源太慢。 – ctacke 2010-11-18 16:27:50

0

聽起來像是你在某處丟失了一個EndInvoke?還是不關閉你的連接?

可能不是問題,但我的工作只是在這裏有一個類似的問題......一對夫婦失蹤的EndInvoke調用完全鎖定我們的服務器後幾天的正常運行時間....喜歡足夠的地方我們不得不下去並強硬啓動盒子。