2009-06-10 28 views
7

Tôi có một ứng dụng WPF trong số những thứ khác hiển thị rất nhiều hình ảnh, lớn và nhỏ. Vấn đề của tôi là ứng dụng sử dụng rất nhiều bộ nhớ và tôi không thể biết được nó đến từ đâu.bộ nhớ của tôi đi đâu? số byte riêng lớn tính

Kịch bản, khi nhấn mạnh ứng dụng một số tôi nhận được biểu đồ này trong perfmon:

http://www.imagechicken.com/uploads/1244548604007097000.jpg

Dòng đen lớn là Process \ byte tư nhân và các dòng khác là các quầy CLR mem (một trong những hồng được Tổng byte cam kết)

trong số trong đồ thị là:
Private byte ~ 350 Mb
byte cam ~ 100 Mb

Tôi đã đào bới rất nhiều với WinDbg và các công cụ khác, và tất cả đều báo cáo rằng hoạt động ngăn xếp được quản lý (! Eeheap báo cáo tổng số chồng được quản lý khoảng 100 Mb)

Tôi đã tham gia các ứng dụng như LeakDiag, LDGrapher nhưng không tìm thấy gì cả.

Vì vậy, cuối cùng là câu hỏi của tôi, làm cách nào để tiếp tục tìm ra nơi bộ nhớ của tôi đang diễn ra?

Thậm chí chỉ mới bắt đầu ứng dụng sử dụng 100Mb theo byte đã cam kết nhưng 190Mb tính theo byte riêng.

Tài liệu tham khảo:

Tôi đã đọc rất nhiều về vấn đề này, trong số những người khác trên các trang web lớn:

Tess Ferrandez: http://blogs.msdn.com/tess/archive/2009/02/27/net-memory-leak-reader-email-are-you-really-leaking-net-memory.aspx

Rico Mariani: http://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx

MSDN mag: http://msdn.microsoft.com/en-us/magazine/cc163528.aspx

+0

Cảm ơn đã trả lời cho đến nay. Vì vậy, để làm rõ, eeheap,! Dumpheap, gcroot vv tất cả các báo cáo những thứ tạo nên 100Mb - những gì tôi đang cố gắng để thoát khỏi là bộ nhớ khác - 250 Mb bổ sung. – andyhammar

+0

Cập nhật - với VADUMP: Báo cáo "Tổng bộ làm việc" là 236 Mb, "Dữ liệu khác" là 196 Mb. Eeheap báo cáo "kích thước heap GC" tại 107336836. Sự khác biệt này là gì? – andyhammar

+0

'Dữ liệu khác' bao gồm heap GC cùng với các dữ liệu khác :) Tôi không chắc chắn có gì khác trong đó, nhưng nó an toàn để giả sử dữ liệu thời gian chạy của nó yêu cầu của CLR. –

Trả lời

1

Tải xuống MemProfiler từ Scitech. Nó có một phiên bản dùng thử 14 ngày.

Sự cố bạn báo cáo thường do lượt xem/tài nguyên không thể xử lý do có gốc trong heap. Một nguyên nhân phổ biến không phải là xử lý sự kiện không mong muốn.

+0

Cảm ơn Mitch. Chỉ cần chơi xung quanh với MemProfiler một chút và tìm thấy một LOT của byte [] từ "MergedDictionaries" (một điều WPF). Đang cố khắc phục điều đó ngay bây giờ. Đây không phải là tất cả, nhưng một cái gì đó, cảm ơn bạn! – andyhammar

3

Chỉ vì ứng dụng của bạn sử dụng nhiều bộ nhớ không cần thiết có nghĩa là bạn bị rò rỉ bộ nhớ. Từ thông tin trong câu hỏi của bạn rất khó để khẳng định điều gì có thể sai.

Khi xử lý sự cố rò rỉ bộ nhớ được quản lý với WinDbg tôi làm như sau:

  • Xem tổng quan về việc sử dụng đống với !eeheap (điều này báo cáo việc sử dụng đống và không phải là chồng như bạn đề cập đến - mỗi stack có một kích thước mặc định là 1 MB, vì vậy trừ khi bạn đã thay đổi điều này, không có cách nào bạn có thể sử dụng 100 MB trên ngăn xếp)

  • Làm !dumpheap -stat để tìm hiểu xem có gì trên heap. Rất có thể là nếu bạn có một bộ nhớ bị rò rỉ các loại tội phạm (s) sẽ là một trong những người tiêu dùng hàng đầu.Để có được một ý tưởng về cách sử dụng heap phát triển, bạn có thể tiếp tục ứng dụng của bạn, phá vỡ nó một chút sau đó và lặp lại lệnh !dumpheap -stat.

  • Nếu bạn tìm thấy bất kỳ loại nào có nhiều phiên bản hơn bạn sẽ loại trừ, hãy liệt kê những trường hợp đó bằng cách sử dụng !dumpheap -mt <MT of type>. Điều này sẽ liệt kê tất cả các trường hợp của loại cụ thể. Chọn các trường hợp ngẫu nhiên và kiểm tra rễ bằng cách sử dụng lệnh !gcroot. Điều này sẽ cho bạn biết những gì giữ các trường hợp trong câu hỏi còn sống. Nếu không có gốc thì những trường hợp này sẽ được thu thập tại một số thời điểm.

CẬP NHẬT trả lời nhận xét của bạn:

Các đống quản lý chỉ là một phần của bộ nhớ một ứng dụng quản lý. Hãy nhớ rằng, một ứng dụng .NET thực sự là một ứng dụng bên trong một ứng dụng khác - quá trình lưu trữ, sẽ nạp CLR, để tải ứng dụng của bạn. Vì vậy, trước khi ứng dụng của bạn bắt đầu sử dụng bất kỳ bộ nhớ nào, CLR đã chiếm một phần đáng kể. Trên hết các ứng dụng .NET lưu trữ cả mã MSIL lẫn mã JIT được biên dịch như là một phần của bản in chân. CLR chiếm không gian cho nhiều công cụ kế toán khác nhau (ví dụ: CLR tạo hai AddDomain bổ sung để sử dụng nội bộ).

Các số bạn cung cấp không tấn công tôi như trên đầu trang, nhưng vì tôi không biết ứng dụng của bạn nên khó có thể nói được nếu quá nhiều.

100 MB trên heap được quản lý có thể không sao, tùy thuộc vào ứng dụng của bạn đang làm gì. Bạn đã kiểm tra đống chưa? Và nếu vậy bạn đã tìm thấy gì?

+0

Cảm ơn Brian! Với heapsize 139 596 684, người dùng mem lớn nhất của tôi là: 1) System.Byte [] (14949 mục, mem: 32 217 996), 2) System.String (475 010 items, mem: 31 016 248) và 3) System.Windows.Markup.BamlDefAttributeKeyStringRecord (mục: 230 845 mem: 11 080 560). Các byte [] s là từ việc đọc hình ảnh từ đĩa và tạo BitmapSources. Các chuỗi tôi không biết, có lẽ là một điều WPF ... – andyhammar

+0

Một mẫu khác: tổng số cam kết: 178 Mb, byte riêng: 538 Mb. Đào thêm ... – andyhammar

1

Bạn có thể thử đọc this article in the latest MSDN magazine. Nó đi vào chi tiết về cách sử dụng VADump để hiểu thêm về nơi bộ nhớ của một quá trình được dành.

Bạn có thể tải VADump đây: http://go.microsoft.com/fwlink/?LinkId=149683

Để phá vỡ đống quản lý, bạn có thể thử một hồ sơ bộ nhớ. Cá nhân tôi thích JetBrains dotTrace.

+0

Cảm ơn Drew, vadump đã không làm việc cho tôi ngày hôm qua nhưng tôi đã thử nó ngay bây giờ - báo cáo số không phù hợp với eeheap. Tôi đã đăng một bình luận cho câu hỏi của mình. – andyhammar

4

Tôi gặp sự cố tương tự trong ứng dụng WPF và used UMDH to track nơi bộ nhớ riêng được cấp phát. (Lưu ý rằng nó thường hữu ích cho set _NT_SYMBOL_PATH để nhận các dấu vết ngăn xếp tốt từ các thành phần hệ điều hành.

Nhật ký cho thấy gần như tất cả bộ nhớ đã được cấp phát trong trình điều khiển video. . hết hạn; tôi đã cài đặt phiên bản mới nhất từ ​​trang web của nhà sản xuất và khắc phục vấn đề

0

một câu trả lời: Nó đi vào con đường quá nhiều ResourceDictionaries sáp nhập (một điều WPF)

Chi tiết: để có thể nhìn thấy thiết kế trong thời gian thiết kế trong Blend và VS, chúng tôi đã sử dụng để hợp nhất từ ​​điển tài nguyên chủ đề của chúng tôi trên hầu hết các trang xaml. được tải cho mỗi điều khiển, bạn có thể đọc thêm thông tin tại đây: [Các đối tượng WPF] [1]

Vì vậy, nơi duy nhất tôi hợp nhất bây giờ là App.xaml.cs:

<Application.Resources> 
    <ResourceDictionary> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary 
     Source="pack://application:,,,/Company.Themes;Component/AppTheme.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Kết quả: (chạy ứng dụng thông qua một số trang với một thử nghiệm giao diện tự động)

Trước:

  • Sau khi tải ứng dụng: 63 Mb
  • Sau khi sử dụng ứng dụng : 177 Mb

Sau:

  • Sau khi tải ứng dụng: 53 Mb
  • Sau khi sử dụng ứng dụng: 97 Mb

tôi sẽ gửi nhiều câu trả lời như tôi tìm thấy chúng! (Tôi nghĩ rằng nó sẽ là dễ nhất cho người đọc thấy phát hiện của tôi như là câu trả lời riêng biệt thay vì replys để bình luận - tốt?)

[1]: ref: http://groups.google.com/group/wpf-disciples/web/wpf-and-xaml-coding-guidelines?pli=1

Các vấn đề liên quan