2015-05-14 39 views
5

我的IIS應用程序(.NET 4.0,IIS7)在內存中不斷增長,並最終倒塌,就像我有內存泄漏一樣。w3wp.exe垃圾堆滿了免費的對象空間,並繼續增長

所以我在DMP達到1.7GB左右的時候開啓了WinDbg。

的dumpheap -stat命令顯示,雖然我在堆有對象了相當數量的,(看連續的疾病管理計劃時所增長,位)大部分被標記爲「自由」(> 800MB):

000007feef55b768 46091 2212368 System.Data.DataRowView
000007fe9739dda8 10355 2236680 Newtonsoft.Json.Serialization.JsonProperty
000007fef4260610 33062 2644960 System.Signature
000007fef4242250 41809 4682608 System.Reflection.RuntimeMethodInfo
000007fef424f05 8 69232 8847997 System.Byte []
000007fef4241b28 11 9437680 System.Double []
000007fef4237ca0 15 9505176的System.DateTime []
000007fef424c168 32559 11009308 System.Char []
000007fef424dc30 17271 11795376 System.Int32 []
000007feef555c48 908 17936672 System.Data.RBTree`1 + Node [[System.Int32,mscorlib]] []
000007feef554f58 853 22056952 System.Data.RBTree`1 + Node [[System.Data.DataRow,System.Data]] []
000007feef5514b0 541444 51978624 System.Data.DataRow
000007fef424aee0 1550958 132599872 System.String
000007fef422f1b8 183607 178409288 System.Object的[]
0000000000d8b2d0 234017 844500226免費

所以我然後跑 「!dumpheap型免費」 這給了我微小的免費對象的很多(每個94個字節準確!)並且朝向端部的一對較大的 「免費」 的對象:

00000003098a59b0 0000000000d8b2d0 134免
00000003098c19d0 0000000000d8b2d0 102免
00000003098ffa00 0000000000d8b2d0 54
0000000309a41d98 0000000000d8b2d0 5961750免
000000041f8a1000 0000000000d8b2d0 24自由自由
000000042001b4d0 0000000000d8b2d0 16933078免費
00000004211bf7c8 0000000000d8b2d0 7702免費
00000004212c1600 000000 0000d8b2d0 35173374免費
00000004236b3be0 0000000000d8b2d0 66886免費
0000000423cc41e8 0000000000d8b2d0 10778318免費
0000000424768928 0000000000d8b2d0 2254734免費
00000004249ec128 0000000000d8b2d0 21166350免費
000000042600f1e0 0000000000d8b2d0 51366免費
000000042621bac8 0000000000d8b2d0 114007238免費

Statistics: 
       MT Count TotalSize Class Name 
000007fef31e7460  1   32 System.Net.SafeLocalFree 
0000000000d8b2d0 234017 844500226  Free 
Total 234018 objects 

注意到重複的廣告的 「d8b2d0」 裝扮我跑了 「gcroot d8b2d0!」 到我得到了以下結果:

0:! '!GCRoot - 所有' 000> gcroot d8b2d0
找到0獨特的根(奔跑看到所有的根)。

所以...畢竟那......我有大量的自由物體粘在我的堆上,GC沒有釋放。這會花費大約2-3個小時。實際類型化的對象沒有任何內存泄漏的跡象。它發生在幾乎所有生產中的虛擬機上。

有沒有人有任何想法如何處理GC在堆上留下這麼多自由對象空間?

它讓我在圈內跑了幾天。所以帽子的天才,可以幫助我找出這一個!

+0

這是一個Asp.Net應用程序?任何特定的框架或庫使用? – ljubomir

+0

是的,它是asp.net。它主要是DataTables和一些使用net.pipe的本地WCF。 – StackedActor

+0

你有任何可以直接分配'GCHandle'的互操作代碼或代碼嗎?我在想,也許你有很多*固定*的對象,防止壓縮。 –

回答

1

感謝有關使用PerfView的建議magicandre1981,並經過了一些非常大的內存轉儲後,我將這個問題放在Linq表達式中使用DataRow.DefaultIfEmpty()。它是在兩個DataTable之間執行LeftJoin的支持函數的一部分。

使用DataRow枚舉中的DefaultIfEmpty()作爲Linq表達式的一部分,我可以在幾分鐘內重新創建內存天空飛躍至4GB +。通過創建大量的ItemArrayObjects(包括小型和大型對象堆),其中大部分都可以繼續使用Gen2 GC集合。這反過來導致了不斷攀升的承諾記憶價值。 GC2集合無法保持在小堆上,而且大堆會遭受糟糕的(如果有的話)重用。

我們已經採取了這個呼籲,同樣的娛樂永遠不會超過承諾的內存50MB。我們現在需要看看這對我們的DataTable連接有什麼影響,但是內存堆的神祕性已經解決了!

感謝您的幫助。

0

如果您確定您的應用程序有內存泄漏,我建議您使用內存分析器啓動本地分析。這可能比分析生產中的內存轉儲更快地揭示問題的根源。

+0

感謝您的建議。我經歷了所有這些。沒有內存泄漏,這導致我調查內存DMP文件。從上面的分析中,它證實(我相信)確實沒有內存泄漏。否則,那個大的800MB +塊會有一個gcroot或至少是某種類型的對象類型。相反,它實際上被標記爲* free *,但GC不會釋放它!? – StackedActor