2011-12-20 21 views
8

Trong ngày tôi thấy rất nhiều bộ sưu tập gen 2 trong dịch vụ cửa sổ của chúng tôi.Khi nào GC quyết định thu thập thế hệ 2?

Khi nào GC quyết định thực hiện thu thập đầy đủ thay vì chỉ thu thập Gen1 và Gen0 hoặc chỉ Gen0?

+0

Có thể khi cảm thấy áp lực giải phóng bộ nhớ. Và có thể khi hệ thống không hoạt động. Chỉ cần đoán thôi. –

Trả lời

9

Đọc http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx và các bài viết được liên kết để biết thêm thông tin. Nói chung, gen2 được thu thập "khi cần thiết".

Một điều có thể gây ra quá nhiều bộ sưu tập Gen2 là khối đối tượng lớn (LOH). Khi LOH được lấp đầy, nó sẽ kích hoạt một bộ sưu tập đầy đủ. Nếu ứng dụng của bạn phân bổ và giải phóng rất nhiều đối tượng lớn (80K hoặc lớn hơn), điều đó rất có thể là vấn đề của bạn.

Xem CLR Inside Out: Large Object Heap Uncovered.

Đồng thời xem xét sử dụng trình thu gom rác của máy chủ trong dịch vụ của bạn. Nó thường sẽ cung cấp hiệu suất tốt hơn (ít bộ sưu tập hơn). Thêm tệp này vào tệp app.config của bạn:

<configuration 
    <runtime> 
     <gcServer enabled="true"/> 
    </runtime> 
</configuration> 
+0

Dịch vụ của chúng tôi sẽ kiểm tra nếu có việc phải làm và xếp hàng trong ThreadPool. Tôi nghĩ rằng những ThreadPool Threads là những người duy nhất đi đến Gen2. Chúng tôi không phân bổ các vật thể lớn. Nhưng tôi thấy bộ sưu tập Gen2 khi bộ nhớ hệ thống thấp. Chế độ máy chủ AFAIK là mặc định khi bạn sử dụng CPU đa lõi. –

+0

@Peri Nếu bộ nhớ hệ thống của bạn thấp, nó sẽ kích hoạt một GC đầy đủ. Hệ thống cần không gian trở lại !. Bạn có thể muốn xem xét khả năng bổ sung thêm RAM. – Joe

+2

@Peri: Không, chế độ máy chủ không phải là mặc định. GC đồng thời là mặc định khi bạn sử dụng đa lõi, nhưng đó vẫn là GC khách hàng. Nếu bạn muốn GC máy chủ, bạn phải nói như vậy trong tập tin app.config của bạn. Ngoài ra, bạn có chắc chắn rằng bạn không phân bổ các đối tượng lớn? Trên hệ thống 64 bit, danh sách chỉ có 10.000 mục trong đó sẽ yêu cầu mảng sao lưu lớn hơn 80 kilobyte. –

5

chung một thức bộ sưu tập được kích hoạt (dưới bất kỳ thế hệ) khi 1 trong các cách sau được đáp ứng

  • Allocation vượt quá ngưỡng. Tôi xin ghi nhớ điều này là năng động dựa trên nhu cầu hiện tại. Bất cứ ai có thể xác nhận/từ chối?
  • Có một Memory Tình hình thấp
  • Nó được gọi là qua GC.Collect()

Có thể có một kịch bản tôi đang mất tích, nhưng nhìn chung đó là nó. Đầu tiên là thường là bắt đầu một bộ sưu tập, và conisdering nó là (relativly) đắt hơn để thu thập G2 hơn G0 bạn thấy ít hơn của họ.


Để giải quyết những câu hỏi trong comment:
Mỗi thế hệ đều có một ngưỡng mà khi hit sẽ kích hoạt một bộ sưu tập. Gen0 có thể là 5mb và sẽ được kích hoạt khi được lấp đầy. Sau khi GC chạy, nếu bạn vẫn còn có 5mb trong đó, tôi tin rằng nó sẽ tăng giới hạn. Nếu nó không phải là tất cả các phân bổ sẽ kích hoạt một bộ sưu tập, và bạn có một vấn đề. Gen2 có thể là 20mb (lưu ý tôi đang tạo số ở đây) và cùng một logic áp dụng ở đó.

Ví dụ về sách giáo khoa, hãy xem xét một tình huống đơn giản.

  1. Đối tượng được phân bổ ứng dụng mới và tất cả được đặt tại Gen0 cho tổng số 3MB dữ liệu. (đây là không phải là luôn luôn như vậy, nhưng giả vờ là)
  2. Lần truy cập GC và 1 MB trong số đó được chuyển đến G1, phần còn lại được dọn sạch.
  3. G0 hiện đã miễn phí và G1 có 1MB trong đó.
  4. Các đối tượng khác được tạo và nhiều sự kiện khác của GC xảy ra. Sau một thời gian G1 được đầy đủ, và một số được chuyển đến G2.
  5. Đối tượng ở đó cho đến khi G2 đầy, và sau đó chúng được làm sạch nếu không sử dụng. Nếu một đối tượng vẫn đang được tham chiếu, nó sẽ vẫn ở trong G2 cho đến khi nó có thể được làm sạch.

GC đầy đủ là tốn kém, và tôi đã thấy ngày trôi qua mà không xảy ra. Cấp này đã được trên một hệ thống với> 64GB ram có sẵn, và không có nhu cầu cho nó.

+0

Ý bạn là gì ở điểm đầu tiên? Đó là ví dụ khi tôi phân bổ <5MB nó chỉ thu thập Gen0 (trên mỗi phân bổ?), Gen1 khi tôi phân bổ 5-10MB và Gen2 khi tôi phân bổ nhiều hơn sau đó 10MB? –

+0

Tôi không chắc mình hiểu ví dụ này. Tôi nghĩ rằng các đối tượng được chuyển đến các thế hệ cũ khi chúng tồn tại GC (vẫn còn sống) chứ không phải khi thế hệ là 'đầy đủ'. –

+0

đúng, khi một GC xảy ra là chìa khóa, và là "đầy đủ" sẽ kick nó đi (hoặc một trong 2 lý do khác đặt ra ở trên). Tôi chỉ sử dụng nó như một ví dụ. – Joe

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