Tôi đang điều tra vấn đề rò rỉ bộ nhớ với PerfMon & WinDbg. Tôi đã nhận thấy bộ đếm 'bộ nhớ lớn' được tăng từ 10MB lên 37MB. Sau khi ép một GC nó chỉ có thể giảm xuống còn 28MB. Ý nghĩa của khối 'Tự do' đối tượng đống lớn khi đổ với WinDbg
(Không có vấn đề bao nhiêu thời gian tôi lặp lại thao tác (tạo/hủy), sau GC, khối đối tượng lớn ổn định ở 28MB).
Tôi muốn biết đối tượng nào gây ra vấn đề rò rỉ, vì vậy tôi chạy WinDbg với '! Dumpheap -min 85000' comand. Chụp hai ảnh chụp nhanh, ảnh chụp đầu tiên được thực hiện trước khi rò rỉ bộ nhớ; Điều thứ hai là sau khi bộ nhớ bị rò rỉ:
Trước:
MT Count TotalSize Class Name
6f39fb08 1 89024 System.String
6f3a4aa0 1 107336 System.Byte[]
6f356d84 2 262176 System.Object[]
00360e4c 1 350392 System.Collections.Generic.Dictionary`2+Entry[Int64,Int32][]
6f3a2a94 3 592584 System.Int32[]
00360c24 1 727072 System.Collections.Generic.Dictionary`2+Entry[String,Int64][]
0bc78b34 4 2754488 System.Collections.Generic.Dictionary`2+Entry[Int64, AccountNode][]
00730260 10 5375572 Free
Sau:
MT Count TotalSize Class Name
6f39fb08 1 89024 System.String
6f3a4aa0 1 107336 System.Byte[]
6f3a55d8 2 202080 System.Collections.Hashtable+bucket[]
6f356d84 2 262176 System.Object[]
00360e4c 1 350392 System.Collections.Generic.Dictionary`2+Entry[Int64,Int32][]
00360c24 1 727072 System.Collections.Generic.Dictionary`2+Entry[String,Int64][]
6f3a2a94 4 738008 System.Int32[]
6cf02838 1 872488 System.Collections.Generic.Dictionary`2+Entry[[MS.Internal.ComponentModel.PropertyKey, WindowsBase],[MS.Internal.ComponentModel.DependencyPropertyKind, WindowsBase]][]
0bc78b34 4 2754488 System.Collections.Generic.Dictionary`2+Entry[Int64, AccountNode][]
00730260 14 21881328 Free
Total 31 objects
Camparing hai ảnh chụp này, sự khác biệt nhất là kích thước của 'miễn phí'. kích thước của nó đã tăng gần 16MB. Bất cứ ai có thể cho tôi biết ý nghĩa của 'Tự do' là gì, đó có phải là không gian trống không? Sự gia tăng có phải do các mảnh vỡ không?
Theo this article, bộ đếm hiệu suất 'Kích thước khối đối tượng lớn' có vẻ bao gồm dung lượng trống. Vì vậy, trong trường hợp của tôi, không có quá nhiều rò rỉ bộ nhớ trên heap đối tượng lớn, chỉ có 2MB (= 28 - 10 -16), phải không?
Nó không phải là một rò rỉ. Điều này là bình thường. Do * not * gọi GC.Collect(), nó rất bất lợi. Đừng theo đuổi "rò rỉ" cho đến khi chương trình của bạn bắt đầu sử dụng quá nhiều lượng hoặc bộ nhớ hoặc bị treo với OOM. 37MB là đậu phộng. Tự học với một cuốn sách hay như C# của Richter thông qua CLR. –
Cảm ơn bạn đã trả lời. Tôi đồng ý với bạn rằng chúng tôi không nên gọi GC.Collect() trong mã sản phẩm. Tôi không hiểu tại sao không đuổi theo "rò rỉ" vấn đề? Như tôi biết, càng nhiều 'rác' ở trong đống, càng nhiều GC xảy ra. Theo tôi, chúng ta nên theo đuổi nó và cắt giảm sự không cần thiết (nghĩa là sự kiện không đăng ký), có thể gây ra vấn đề rò rỉ bộ nhớ. – Anders06