2013-01-16 20 views
6

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. enter image description hereÝ 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?

+2

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. –

+0

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

Trả lời

0

Ý nghĩa của đống đối tượng lớn là well explained here.

Đối tượng lớn là đối tượng có kích thước lớn hơn 85kb, được lưu trữ trong khu vực đó và chỉ được thu thập khi thế hệ 2 sẽ được khai hoang.

+0

@Devil, Cảm ơn bạn đã trả lời. Tuy nhiên tôi không hỏi câu hỏi về 'đống vật thể lớn' nhưng mục 'Tự do' được hiển thị trong WinDbg. – Anders06

+0

GC trong khi thực hiện một ứng dụng phân bổ và deallocates đối tượng, do đó, heap phát triển, nhưng nó sẽ không co lại thành từng deallocation vì lý do hiệu suất. Làm như vậy, ứng dụng có thể nhận đủ chỗ cho các đối tượng mới mà không cần cấp phát thêm bộ nhớ. Các cơ chế nội bộ GC, đôi khi, đòi lại một phần của đống chưa sử dụng thu hẹp nó. Tôi nghĩ rằng MIỄN PHÍ là sự khác biệt giữa tổng kích thước đối tượng và phân bổ hiện tại. –

+0

Liên kết trong câu trả lời là đã chết – Kamarey

5

MIỄN PHÍ cho biết khối bộ nhớ không sử dụng trên heap. Các khối miễn phí trên LOH được mong đợi, bởi vì LOH không bao giờ bị nén lại. Thay vào đó, một danh sách không gian FREE được giữ lại cho LOH. Các khối miễn phí trên heap GC thông thường, với một vài ngoại lệ, chỉ ra sự phân mảnh do việc ghim các đối tượng. Khi GC gặp một đối tượng được ghim, sự nén chặt của đoạn được tạm dừng và bộ nhớ được tiêu thụ bởi các đối tượng không sử dụng được đánh dấu là MIỄN PHÍ. Những gì bạn nhìn thấy trên LOH là bình thường. Hãy nhớ rằng LOH là không bao giờ nén và phân đoạn bộ nhớ được phân bổ cho LOH không bao giờ được giải phóng, vì vậy LOH không bao giờ co lại.

+0

Điều này. Phần có vấn đề nhất về đống đối tượng lớn là thiếu sự nén chặt này, có thể (nếu bạn vô tình lạm dụng nó) dẫn đến phân mảnh heap, về cơ bản điều tương tự xảy ra với ổ cứng của bạn. – JerKimball

+0

Cảm ơn, tôi đã rõ ràng về chỉ báo Miễn phí ngay bây giờ. – Anders06

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