2010-01-11 48 views
2

我的應用程序剛剛泄漏了1.5GB的內存。我想因爲我沒有大量可用的數據,所以我假設它泄露了內存,但它也可能只是保留在內存中。調試應用程序中的巨大內存泄漏

我正在使用perfmon來收集儘可能多的信息,以嘗試瞭解可能導致問題的原因。在這一點上我沒有太多的線索,並希望能從這裏的人那裏獲得更多的線索。

  1. 我可以說的第一件事是我沒有在我的任何類中實現IDisposable。但是,我知道我不會在任何GUI元素上調用Dispose,例如SolidColorBrush。由於我的應用不是以任何方式進行圖形密集處理,我認爲這不會導致問題。不過,我會添加必要的電話。

  2. 我不知道我是否在實現IDisposable的框架中使用任何其他類。我讀了一篇關於FxCop的帖子here on SO。我安裝並用它來分析我的程序集,但它似乎只檢查我自己的類是否正確實現了IDisposable。是否有另一個工具可以告訴我所有實現IDisposable的類?

  3. 我目前在我的應用程序中使用WF,並且WF正在不斷啓動和完成。 Perfmon顯示WF正在正常結束,並且我正在使用「使用」關鍵字,我知道這是爲我處理正確的處置。

  4. 有沒有簡單的方法來判斷內存是否「泄漏」來自非託管或託管代碼?

  5. 當我得到OOM異常時,該應用程序正在使用77k +手柄。

有關如何繼續下一步的任何提示將不勝感激。我打算再次運行該應用程序並監視性能計數器,並可能剔除某些調用。爲了比較的緣故,我也可以運行模擬,因爲在該模式下它不會調用我的C DLL。

+0

我也剛剛安裝並運行了CLR Profiler,它似乎從未真正附加到我的過程。它啓動我的應用程序,但是「等待應用程序啓動公共語言運行時」的窗口永遠保留在屏幕上。當我關閉我的應用程序時,它仍然只是坐在那裏。所以,也許它終究不適用於.NET 3.5。 – Dave 2010-01-11 18:58:27

+0

它適用於.NET 3.5。 – 2010-01-11 19:58:12

+0

我之前也有過這個問題,我認爲修正是以管理員身份運行它。 – 2010-09-12 21:31:31

回答

4
+0

現在閱讀! :) 謝謝! – Dave 2010-01-11 19:19:55

+0

問題還沒有100%解決,但這個答案是最接近的,併爲我提供了大量有用的信息來研究和了解非常相關的主題。這太棒了! 使用ANTS,我能夠將泄漏縮小到創建WorkflowRuntime。儘管我使用「使用(WorkflowRuntime wr = new WorkflowRuntime()){}」創建了運行時,但每次都會泄漏大量內存。根據一大堆搜索結果,這個bug現在應該已經被修復了。我目前的「解決方案」僅用於測試目的是使用單身。 – Dave 2010-01-12 15:09:29

+0

單身並不是100%正確的IMO,因爲我需要能夠區分不同的工作流程。我同時運行多達8個,如果其中任何一個遇到錯誤,我需要知道哪一個。你怎麼能確定哪個WF有錯誤?也許這是另一個問題的主題。 :) – Dave 2010-01-12 15:11:27

0

Use CLR Profiler找出你正在泄漏的東西。然後修復它。

+0

幾分鐘前我剛剛發佈了一條評論意見 - CLR Profiler似乎沒有正常工作。它啓動我的應用程序,但只是坐在那裏等待CLR啓動,顯然。 – Dave 2010-01-11 19:02:43

2

紅門有一個內存分析器(http://www.red-gate.com/products/ants_memory_profiler/index.htm),這對於這些類型的東西非常有用。我強烈推薦它。 30天試用。

蘭迪

+0

很酷,我會安裝它。最初我在那裏有SciTech的分析器。幾周前我曾問過紅門進行個人演示,但他們拒絕了。 :)猜猜我會捲起袖子,然後嘗試。 – Dave 2010-01-11 19:03:45

2

你去投資工具之前,你應該嘗試找出漏水...

您已經連接perfmon,然後這是偉大的。我會監視以下perfpounters。

流程\ PrivateBytes 過程\句柄計數 流程\的NonPagedPool

.NET CLR內存*

如果您的專用字節不斷增長,以及.NET CLR內存\ BytesInAllHeaps,它指向一個管理泄漏。後續步驟:進行轉儲並使用CLR Profiler進行分析,或者將windbg.exe附加到進程,加載sos擴展dll並分析您的託管堆以查找泄漏。

如果私有字節增長,.NET CLR內存*計數器沒有相應的增加,那麼它指向非託管泄漏。您必須將windbg.exe附加到進程並使用!堆擴展來檢查進程堆。

如果您看到單調增加的HandleCount以及NonPagedPool,則會出現句柄泄漏 - 這可能是託管代碼或本機代碼。您必須弄清楚哪些句柄正在泄漏 - 您可以使用sysinternals中的processmon.exe來獲取句柄列表,並進一步調查。

希望這會有所幫助。

+0

不幸的是,我已經關閉了應用程序,所以我可以嘗試分析,但我沒有檢查Private Bytes值,它是1.5GB。不幸的是,我沒有添加NonPagedPool。 BytesInAllHeaps也是1.5GB。感謝您的有用信息! – Dave 2010-01-11 19:09:32

+0

好的,現在我知道它絕對來自我的工作流程。我使用{}創建運行時,然後調用CreateWorkflow並將其傳遞給我的順序工作流的新實例。如果我第一次編寫代碼的時候我更聰明,那麼我會讓工作流運行時成爲單例,而不是每次都實例化一個新的代碼。我會先做,看看會發生什麼。但是,即使我這樣做,不應該使用{}稱爲Dispose對我? – Dave 2010-01-11 23:29:15

+0

哎呦,爲了澄清,我想我應該創建WF運行時池,因爲我肯定會一次需要多個運行時。 – Dave 2010-01-11 23:40:02

0

不直接回答你的問題,但我總是使用Process Explorer它顯示進程虛擬大小,工作集,Gen 0,1和2集合和私人字節(與非託管內存有關)。基本上它只是一個不錯的用戶界面,適用於普通的Windows任務管理器和性能計數器。可以幫助您觀察應用程序的與內存相關的行爲。

+0

這就是我使用perfmon的方式,它會給你相同的信息,並且它已經內置到窗口中。這只是不漂亮,但報告視圖很好地工作IMO。 – Dave 2010-01-12 15:06:10