2011-08-08 10 views
7

Tôi đang làm việc để gỡ lỗi một ứng dụng có vẻ như bị rò rỉ bộ nhớ như điên; hầu hết nó có vẻ là do sự phân mảnh từ các đối tượng được ghim (tải xuống dữ liệu hình ảnh trong một WriteableBitmap). Tuy nhiên, tôi không cố ý sử dụng GC.Handle hoặc bất cứ điều gì giống như nó. Tất cả những gì tôi làm là lưu trữ dữ liệu trong một MemoryStream và tham khảo nó như thế.Điều gì có thể "Ghim" một đối tượng trong bộ nhớ trong Silverlight?

Dữ liệu ghim hoạt động nào trong bộ nhớ, không rõ ràng như vậy? Ngoài ra, làm thế nào tôi có thể tìm thấy những gì pinned nó bằng cách sử dụng WinDbg?

CHỈNH SỬA: Theo yêu cầu, đây là đầu ra (hơi được khử trùng) của một trong một! GCRoot trên mảng System.Int32 liền kề với một khối lớn bộ nhớ trống. Đây là đại diện cho tất cả các khối lớn miễn phí.

EDIT 2: Sau khi dành thời gian với những người bạn mới của tôi WinDbg và SOS, tôi thấy rằng WriteableBitmapsMemoryStream đối tượng, đều 'gắn', và cần được phân bổ một cách cẩn thận để ngăn ngừa sự phân mảnh bộ nhớ. Đọc bài báo từ câu trả lời được chấp nhận để giải thích tại sao cần phải làm như vậy.

DOMAIN(1AC72358):HANDLE(Pinned):72c12f8:Root: 174c5e20(System.Object[])-> 
    16533060(Project.ProjectParts.PartContainer)-> 
    167fe554(Project.ProjectParts.Part.PartActivity)-> 
    167d21d8(Project.ProjectParts.Sprites.Graphic)-> 
    16770f28(System.Windows.Controls.Canvas)-> 
    16770e1c(System.Windows.Controls.Canvas)-> 
    16770ee4(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    1680e778(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    16770f9c(System.Windows.Controls.Canvas)-> 
    16819114(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    16819160(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    16818df4(System.Windows.Controls.Canvas)-> 
    16818e58(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    16819f10(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    168194c4(System.Windows.Controls.Canvas)-> 
    16819528(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    16819574(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    16819370(System.Windows.Controls.Image)-> 
    21c82138(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    21c82184(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    168195dc(System.Windows.Media.Imaging.WriteableBitmap)-> 
    21c7ce2c(System.Int32[]) 
DOMAIN(1AC72358):HANDLE(AsyncPinned):72c1dfc:Root: 166bae48(System.Threading.OverlappedData)-> 
    1654d448(System.Threading.IOCompletionCallback)-> 
    1654c29c(System.Net.Sockets.SocketAsyncEventArgs)-> 
    1654bad4(System.Net.Sockets.Socket+StaticConnectAsyncState)-> 
    1654ba40(System.Net.Sockets.SocketAsyncEventArgs)-> 
    1654b684(System.ServiceModel.Channels.SocketConnectionInitiator+ConnectAsyncResult)-> 
    1654b414(System.ServiceModel.Channels.ConnectionPoolHelper+EstablishConnectionAsyncResult)-> 
    1654b3b0(System.ServiceModel.Channels.ClientFramingDuplexSessionChannel+OpenAsyncResult)-> 
    1654b380(System.ServiceModel.Channels.CommunicationObject+OpenAsyncResult)-> 
    1654b330(System.ServiceModel.Channels.CommunicationObject+OpenAsyncResult)-> 
    1654b0f4(System.ServiceModel.Channels.ServiceChannel+SendAsyncResult)-> 
    1654b070(System.ServiceModel.ClientBase`1+AsyncOperationContext[[Cassandra.Common.WCF.IAsyncWcfRequestProcessor, Cassandra.Common.Silverlight]])-> 
    1654b05c(System.ComponentModel.AsyncOperation)-> 
    1654b04c(Project.Common.IoC.InvokeAsyncCompletedEventRequestsArgs)-> 
    1654afec(System.Action`1[[Project.Common.IoC.ProcessRequestsAsyncCompletedArgsEx, Project.Common.SL]])-> 
    1654afc8(Project.Common.IoC.AsyncRequestDispatcherEx+<>c__DisplayClass1)-> 
    1654afa0(Project.Common.IoC.NetResponseReceiver)-> 
    1653408c(System.Action`2[[Cassandra.Common.ExceptionInfo, Cassandra.Common.Silverlight],[Cassandra.Common.ExceptionType, Cassandra.Common.Silverlight]])-> 
    16533ffc(Project.ProjectParts.ILE.Services.EngineProxyService+<>c__DisplayClass5)-> 
    16533fdc(System.Action`1[[Cassandra.Common.ReceivedResponses, Cassandra.Common.Silverlight]])-> 
    16533fbc(Project.ProjectParts.ILE.Services.IEngineProxyExtensions+<>c__DisplayClass1`2[[Project.Services.RequestsAndResponses.ListMediaServersByTokenRequest, Project.Services.RequestsAndResponses.Silverlight],[Project.Services.RequestsAndResponses.ListInstitutionMediaServersResponse, Project.Services.RequestsAndResponses.Silverlight]])-> 
    16533f9c(System.Action`1[[Project.Services.RequestsAndResponses.ListInstitutionMediaServersResponse, Project.Services.RequestsAndResponses.Silverlight]])-> 
    1650a2a0(Project.ProjectParts.ILE.MainPage)-> 
    1674ea0c(Project.ProjectParts.ActivityTimer)-> 
    165330a4(Project.ProjectParts.PauseManager)-> 
    165330bc(System.Collections.Generic.List`1[[Project.ProjectParts.IPausable, ActivityFramework]])-> 
    166a8610(System.Object[])-> 
    167ca858(Project.ProjectParts.ActivityTimer)-> 
    167ca838(Project.ProjectParts.ActivityTimerEventHandler)-> 
    16533060(Project.ProjectParts.PartContainer)-> 
    167fe554(Project.ProjectParts.Part.PartActivity)-> 
    167d21d8(Project.ProjectParts.Sprites.Graphic)-> 
    16770f28(System.Windows.Controls.Canvas)-> 
    16770e1c(System.Windows.Controls.Canvas)-> 
    16770ee4(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    1680e778(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    16770f9c(System.Windows.Controls.Canvas)-> 
    16819114(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    16819160(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    16818df4(System.Windows.Controls.Canvas)-> 
    16818e58(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    16819f10(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    168194c4(System.Windows.Controls.Canvas)-> 
    16819528(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    16819574(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    16819370(System.Windows.Controls.Image)-> 
    21c82138(System.Collections.Generic.Dictionary`2[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]])-> 
    21c82184(System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.IManagedPeerBase, System.Windows],[System.Object, mscorlib]][])-> 
    168195dc(System.Windows.Media.Imaging.WriteableBitmap)-> 
    21c7ce2c(System.Int32[]) 
DOMAIN(1AC72358):HANDLE(Pinned):72c2b18:Root: 21c7ce2c(System.Int32[]) 
+0

bạn có thể muốn google "rò rỉ bộ nhớ có thể ghi được bộ nhớ" Tôi nhớ đã đọc về nó một thời gian trước đây. – Denis

+0

Tôi đã thấy những điều đó; và tất cả chúng dường như là những trường hợp khác với trường hợp của tôi, hoặc đã là sáu trường hợp kể từ SL3. –

+0

Bạn có thể chạy '! Gcroot ' đối với đối tượng bạn cho là đã ghim và thêm đối tượng này vào câu hỏi của bạn không? –

Trả lời

1

Giả sử Silverlight hoạt động giống như khuôn khổ .net đầy đủ, đối tượng trên 85k sẽ không bao giờ bị thu gom rác. http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

Chúng tôi đã chia nhỏ các đối tượng hàng đợi lớn thành một dãy các hàng đợi nhỏ hơn, sau đó cho phép thu thập cấu trúc dữ liệu sau khi thu nhỏ lại kích thước chạy bình thường. Trước khi mã này thay đổi, một khi hàng đợi đã vượt quá ngưỡng, bộ nhớ sẽ không bao giờ được phát hành trở lại hệ điều hành.

Đây có phải là những gì bạn đang gặp phải không?

+0

Cảm ơn bài viết đó! Nó rất thú vị. Chúng tôi đã có một số vấn đề với điều đó, đặc biệt là khi một số hình ảnh rất nhỏ đã phân mảnh LOH khủng khiếp. Sắp xếp lại cách những người được phân bổ đã dọn sạch mọi thứ một cách độc đáo. Sử dụng một bộ nhớ .NET Profiler, tôi thấy rằng 450 MB nếu dữ liệu rò rỉ bộ nhớ đang bị mất đến "Unknown Unmanaged Heaps", với dấu vết stack rất khó hiểu và thẳng thắn. Câu trả lời được chấp nhận vì bài viết đề cập đến các nguyên tắc cốt lõi của một số lý do tôi bị rò rỉ - phần khác của rò rỉ là một lỗi trong SL4. –

0

Pin là cơ chế giữ Async hoặc trình xử lý trong các điều khiển của bạn thành "không được di chuyển trong bộ nhớ" trong khi thao tác đang được xử lý hoặc tham chiếu trình xử lý tồn tại.

Bạn cũng nên kiểm tra xem bạn có bất kỳ trình xử lý nào hoặc các hoạt động Async như ứng dụng khách WCF hoặc trạng thái mở của dịch vụ Web Http, trước khi rời khỏi mô hình hoặc mô hình kiểm soát hoặc xem. Nếu bất kỳ đối tượng nào được ghim khi bạn thoát khỏi điều khiển, xem mô hình hoặc mô hình bạn sẽ bị rò rỉ bộ nhớ cho những đối tượng đó.

Cũng xin lưu ý rằng nếu những đối tượng đó kết thúc lên đến hơn 85.000byte, chúng sẽ kết thúc trong thế hệ 2 mà không phải là Thu thập rác cho đến khi ứng dụng (tên miền) chấm dứt.

Nếu đối tượng nhỏ hơn 85K và sống sót GC cho thế hệ 0. Nó được thăng cấp lên thế hệ 1 và khi tồn tại hoặc không được giải phóng hoặc thứ gì đó đang giữ sẽ kết thúc cuộc sống của mình với Thế hệ 2, SL không được thu thập.

Cũng cần lưu ý: nếu bạn giải phóng/phân bổ thường xuyên các đối tượng đó sẽ làm cho bộ nhớ bị phân mảnh. Nếu chương trình của bạn đòi hỏi phải có không gian liên tục trong bộ nhớ và không có khối miễn phí nào lớn vì sự phân mảnh, bạn sẽ thoát khỏi bộ nhớ ngoại lệ.

Hy vọng ở trên sẽ hữu ích.

+1

Hi Alexander, điều này có trả lời bất kỳ câu hỏi nào không ** (1) ** "* Điều gì có thể" Ghim "một đối tượng trong bộ nhớ trong Silverlight? *", ** (2) ** "* Dữ liệu pin hoạt động nào trong bộ nhớ, mà không rõ ràng nói như vậy? * ", hoặc ** (3) **" * làm thế nào tôi có thể tìm thấy những gì pinned nó bằng cách sử dụng WinDbg? * " –