2009-03-10 36 views
9

Chi phí tạo ra nhiều đối tượng tạm thời (tức là đối với kết quả tạm thời) là "chết trẻ" (không bao giờ được quảng bá cho thế hệ tiếp theo trong khoảng thời gian thu gom rác)? Tôi giả định rằng các hoạt động "mới" là rất rẻ, vì nó thực sự chỉ là một con trỏ tăng. Tuy nhiên, chi phí ẩn đối phó với "rác" tạm thời này là gì?Các đối tượng sống ngắn

+0

Nếu bạn thực sự có các đối tượng đơn giản và đặc biệt nếu chúng dễ đặt lại, hãy tạo một nhóm đối tượng và sử dụng lại chúng. Điều này cũng có thể làm việc cho các đối tượng phức tạp. Khi tôi đã có một ứng dụng tạo ra hàng nghìn ảnh bitmap nhỏ để vẽ văn bản nội dung không thể được vẽ trực tiếp trên trang vì lý do logic. Cho 1000s pgs, kích thước đã được tái sử dụng. Thay vì 'vứt bỏ', tôi lưu trữ chúng trong một bảng băm 'miễn phí' với khóa là WidthxHeight (chỉ vào danh sách các bitmap) và kiểm tra nó trước khi thực hiện NEW. Nếu có, hãy tháo nó ra, đặt nó vào sử dụng. Nghe có vẻ đắt tiền, nhưng việc tạo bitmap phải tệ hơn. Tăng tốc rất lớn. – FastAl

+0

@FastAl Tôi giả sử bạn có ý nghĩa giống như ['System.Drawing.Bitmap'] (https://msdn.microsoft.com/en-us/library/system.drawing.bitmap%28v=vs.110%29.aspx) "Đóng gói một bitmap GDI +" ngụ ý [một cái gì đó giống như một syscal để tạo/phá hủy] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724291%28v=vs.85%29. aspx) chúng. Điều đó hoàn toàn khác với các đối tượng thuần túy mà tôi cho là OP đang hỏi. – binki

+0

@binki - Bạn nói đúng về bitmap, nó đắt hơn nhiều so với các đối tượng đơn giản. Nhưng nếu vòng lặp là đủ chặt chẽ và bạn không làm nhiều với các đối tượng ... tăng tốc độ có thể vẫn có giá trị tái sử dụng chúng. GC vẫn phải làm điều gì đó. Tất nhiên trong trường hợp đó, nó phụ thuộc. Ông không đề cập đến kích thước, bitmap có thể là tạm thời và khi bạn đề cập đến có một chi phí khá ẩn đối với họ. Đối tượng mới, nếu lớn, có thể được xóa trước khi sử dụng quá, nếu mã của bạn ghi đè những gì có anyway nó có thể có nghĩa là một tăng tốc 2x (Đó là loại ninja tho). – FastAl

Trả lời

12

Không nhiều - bộ thu gom rác rất nhanh cho gen0. Nó cũng tự điều chỉnh, điều chỉnh kích thước của gen0 tùy thuộc vào số lượng nó quản lý để thu thập mỗi khi nó đi. (Nếu nó được quản lý để thu thập rất nhiều, nó sẽ giảm kích thước của gen0 để thu thập trước đó thời gian tới, và ngược lại.)

Kiểm tra cuối cùng là cách ứng dụng của bạn thực hiện. Perfmon rất tiện dụng ở đây, hiển thị lượng thời gian đã sử dụng trong GC, số lượng bộ sưu tập đã có của từng thế hệ v.v.

+1

Downvoters: bình luận được chào đón, nếu không không ai (kể cả tôi) sẽ biết bạn không đồng ý với câu trả lời của tôi ... –

+1

Tôi lấy PerfMon ở đâu? – Karl

+2

Nó gần như chắc chắn đã được cài đặt trên hộp Windows của bạn rồi. Nhấn Windows-R và chỉ cần gõ "perfmon". Nếu không, việc tìm kiếm nó sẽ phụ thuộc vào phiên bản Windows bạn đang sử dụng. –

3

Như bạn nói bản thân việc phân bổ không tốn kém lắm. Chi phí tạo ra nhiều đối tượng sống ngắn là các bộ sưu tập rác thường xuyên hơn khi chúng được kích hoạt khi ngân sách của thế hệ 0 bị cạn kiệt. Tuy nhiên, một bộ sưu tập thế hệ 0 là khá rẻ, do đó, miễn là đối tượng của bạn thực sự là ngắn sống trên không có nhiều khả năng không đáng kể.

Mặt khác, ví dụ chung về việc nối nhiều chuỗi trong một vòng lặp đẩy bộ thu gom rác đáng kể, vì vậy tất cả phụ thuộc vào số lượng đối tượng bạn tạo. Nó không đau khi nghĩ về phân bổ.

Chi phí thu gom rác là các chuỗi được quản lý bị tạm ngưng trong quá trình nén.

1

Nói chung, đây không phải là điều bạn nên lo lắng và có vẻ như nó bắt đầu giảm rất gần với "tối ưu hóa vi mô". GC được thiết kế với giả định rằng một "ứng dụng được điều chỉnh tốt" sẽ có tất cả các phân bổ của nó trong Gen0 - có nghĩa là tất cả chúng đều "chết trẻ". Bất cứ khi nào bạn phân bổ một đối tượng mới, nó luôn nằm trong Gen0. Một bộ sưu tập sẽ không xảy ra cho đến khi ngưỡng Gen0 được thông qua và không có đủ không gian có sẵn trong Gen0 để giữ phân bổ tiếp theo.

Các "mới" hoạt động thực sự là một loạt các điều:

  1. phân bổ bộ nhớ
  2. chạy các loại nhà xây dựng
  3. trả về một con trỏ tới bộ nhớ
  4. incrementing con trỏ đối tượng kế tiếp
0

Nếu các đối tượng này không bao giờ được quảng bá ngoài Thế hệ 0 thì bạn sẽ thấy hiệu suất khá tốt. Chi phí ẩn duy nhất tôi có thể thấy là nếu bạn vượt quá ngân sách Thế hệ 0, bạn sẽ buộc GC phải nén gọn heap nhưng GC sẽ tự điều chỉnh vì vậy đây không phải là vấn đề đáng lo ngại.

0

Bộ sưu tập rác là thế hệ trong .Net. Các đối tượng sống ngắn sẽ thu thập trước và thường xuyên. Bộ sưu tập Gen 0 là rẻ, nhưng tùy thuộc vào quy mô số lượng đối tượng bạn đang tạo, nó có thể khá tốn kém. Tôi sẽ chạy một hồ sơ để tìm hiểu xem nó đang ảnh hưởng đến hiệu suất. Nếu có, hãy cân nhắc chuyển chúng sang cấu trúc. Đây không cần phải được thu thập.

1

Mặc dù hoạt động mới được thiết kế và viết hiệu quả nhưng nó không phải là miễn phí và mất thời gian để cấp phát bộ nhớ mới. Thư viện cấp phát bộ nhớ cần theo dõi những phần nào có sẵn để cấp phát và bộ nhớ mới được cấp phát bằng 0.

Tạo nhiều đối tượng chết trẻ cũng sẽ kích hoạt thu gom rác thường xuyên hơn và hoạt động đó có thể tốn kém. Đặc biệt là với các nhà sưu tập rác "ngừng thế giới".

Dưới đây là một bài báo từ MSDN về cách hoạt động: http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

Lưu ý: nó mô tả cách gọi thu gom rác thải là tốn kém bởi vì nó cần để xây dựng đồ thị đối tượng trước khi nó có thể bắt đầu thu gom rác thải.

+0

Từ bài viết được liên kết: "Những thử nghiệm này cũng cho thấy rằng nó mất ít hơn 1 mili giây trên một Pentium 200Mhz để thực hiện một GC đầy đủ của thế hệ 0. Đó là mục tiêu của Microsoft để làm cho GC không mất nhiều thời gian hơn một lỗi trang bình thường." IMO "rất đắt". Không miễn phí, chắc chắn, nhưng nếu (tiếp) –

+0

mã dễ đọc hơn với nhiều đối tượng nhỏ, ngắn ngủi thì tôi muốn đi theo cách đó cho đến khi nó được chứng minh là cổ chai hơn là uốn cong thiết kế của tôi ra khỏi hình dạng để chống lại một "vấn đề" hiệu suất mà có thể không phải là một vấn đề gì cả. –

+0

Tôi đồng ý và tôi không nói rằng họ nên thay đổi cách họ viết chương trình. Câu hỏi đặt ra là chi phí cơ bản là bao nhiêu, và tôi đã cố gắng đưa ra câu trả lời. –

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