2010-04-26 36 views
12

OK đây là thỏa thuận. Có một số người đặt cuộc sống của họ trong tay của thu gom rác của NET và một số người chỉ đơn giản là sẽ không tin tưởng nó.Hiệu quả của bộ thu gom rác .NET

Tôi là một trong những người tin tưởng một phần, miễn là nó không thực sự cực kỳ hiệu quả (tôi biết tôi biết .. hiệu suất quan trọng + .net không phải là kết hợp được ưa chuộng), trong trường hợp này tôi muốn tự tay vứt bỏ đối tượng và tài nguyên.

Điều tôi đang hỏi là liệu có bất kỳ sự kiện nào về hiệu quả hoạt động hiệu quả hoặc không hiệu quả của bộ thu gom rác thực sự không?

Vui lòng không chia sẻ bất kỳ ý kiến ​​cá nhân hoặc khả năng dựa trên giả định nào dựa trên kinh nghiệm, tôi muốn các sự kiện không thiên vị. Tôi cũng không muốn bất kỳ cuộc thảo luận chuyên nghiệp/con vì nó sẽ không trả lời câu hỏi.

Cảm ơn

Edit: Để làm rõ, tôi về cơ bản nói: Không có vấn đề gì ứng dụng chúng ta viết, tài nguyên quan trọng hay không chúng ta có thể chỉ cần quên đi tất cả mọi thứ và để cho các GC xử lý nó hay không chúng ta có thể ?

Tôi đang cố gắng để có được câu trả lời trên thực tế những gì GC không và không và nơi nó có thể thất bại nơi quản lý bộ nhớ thủ công sẽ thành công NẾU có những tình huống như vậy. Nó có LIMITATIONS không? Tôi không biết làm thế nào tôi có thể giải thích thêm câu hỏi của mình.

Tôi không có bất kỳ vấn đề nào với bất kỳ ứng dụng nào, đó là một câu hỏi lý thuyết.

+6

xác định hiệu quả. mà không biết làm thế nào bạn muốn đo lường hiệu quả của nó khó khăn của nó để trả lời điều đó. –

+0

Vâng, nếu có thể cố gắng tránh người thân hoặc nếu bạn phải, so sánh nó với một bộ quản lý bộ nhớ hoàn hảo. –

+0

Nếu bạn đang tìm kiếm một số sự kiện không thiên vị, tại sao bạn không tự thiết lập một số thử nghiệm? Chạy qua một số sáng tạo và hủy diệt thủ công, và sau đó chạy cùng một chương trình một lần nữa mà không vứt bỏ bất cứ điều gì và để cho GC nhặt nó lên? Nếu bạn muốn số và bằng chứng giai thoại không ổn cho bạn, hãy thiết lập các bài kiểm tra để tự mình lấy số. – SqlRyan

Trả lời

9

Đủ hiệu quả cho hầu hết các ứng dụng. Nhưng bạn không phải sống trong sợ hãi của GC. Trên các hệ thống thực sự nóng, yêu cầu độ trễ thấp, bạn nên lập trình theo cách hoàn toàn tránh được. Tôi đề nghị bạn nhìn vào Rapid Addition White Paper này:

Mặc dù GC được thực hiện khá nhanh chóng, nó không mất thời gian để thực hiện, và do đó thu gom rác thải trong chế độ hoạt động liên tục của bạn có thể giới thiệu cả độ trễ không mong muốn và sự thay đổi trong độ trễ trong các ứng dụng có độ nhạy cao là để trì hoãn. Như một minh hoạ , nếu bạn đang chế biến 100.000 tin nhắn mỗi thứ hai và mỗi tin nhắn sử dụng tạm thời 2 chuỗi nhân vật nhỏ, khoảng 8 byte ( này một chức năng mã hóa chuỗi và thực hiện của đối tượng string) được phân bổ cho mỗi tin nhắn. Vì vậy, bạn đang tạo ra gần 1MB rác mỗi giây. Đối với hệ thống có thể cần phân phối hiệu suất không đổi trong khoảng thời gian 16 giờ, nghĩa là bạn sẽ phải dọn sạch 16 giờ x 60 phút x 60 giây x 1MB của bộ nhớ khoảng 56 GB bộ nhớ. Điều tốt nhất bạn có thể mong đợi từ các nhà sưu tập rác là nó sẽ sạch này lên hoàn toàn bằng một trong hai thế hệ 0 hoặc 1 bộ sưu tập và nguyên nhân jitter, điều tồi tệ nhất là nó sẽ gây ra một thế hệ 2 rác bộ sưu tập với sự liên quan lớn hơn tăng đột biến độ trễ.

Nhưng được cảnh báo, hãy tắt các thủ thuật như tránh tác động GC là thực sự khó khăn. Bạn thực sự cần phải suy nghĩ xem bạn đang ở thời điểm đó trong các yêu cầu về sự hoàn hảo của bạn, nơi bạn cần phải xem xét tác động của GC.

+0

Cảm ơn một tấn cho thông tin đó, thực sự đánh giá cao nó. –

+0

Đó là một số đọc thú vị và trả lời nhiều câu hỏi của tôi, cảm ơn một lần nữa. –

1

Mọi thuật toán GC sẽ có lợi cho hoạt động nhất định (ví dụ: tối ưu hóa). Bạn sẽ phải kiểm tra GC dựa trên mẫu sử dụng của bạn để xem mức độ hiệu quả của nó đối với bạn. Ngay cả khi người khác nghiên cứu hành vi cụ thể của GC .net và tạo ra "sự kiện" và "số", kết quả của bạn có thể cực kỳ khác nhau.

Tôi nghĩ câu trả lời hợp lý duy nhất cho câu hỏi này giai thoại. Hầu hết mọi người không có vấn đề với hiệu quả GC, ngay cả trong các tình huống quy mô lớn. Nó được coi là ít nhất là hiệu quả hoặc hiệu quả hơn so với GC của các ngôn ngữ được quản lý khác. Nếu bạn vẫn còn lo ngại, có thể bạn không nên sử dụng một ngôn ngữ được quản lý.

+0

Cảm ơn bạn đã trả lời, nó không thực sự là một mối quan tâm Tôi chỉ nghĩ rằng đó là một cái gì đó bạn nên có một số kiến ​​thức về, tôi không đó là lý do tại sao tôi yêu cầu. –

2

Bạn không cần phải lo lắng về điều này.

Lý do là nếu bạn từng thấy một trường hợp cạnh mà GC chiếm một lượng thời gian đáng kể, thì bạn sẽ có thể xử lý nó bằng cách thực hiện tối ưu hóa điểm. Đây sẽ không phải là kết thúc của thế giới - nó có lẽ sẽ khá dễ dàng.

Và bạn không thể tìm thấy các trường hợp cạnh như vậy. Nó thực sự hoạt động rất tốt. Nếu bạn chỉ trải nghiệm các trình cấp phát heap trong các triển khai C và C++ điển hình, .NET GC là một động vật hoàn toàn khác. Tôi đã rất ngạc nhiên bởi nó I wrote this blog post to try and get the point across.

2

Bạn không thể luôn luôn quên phân bổ bộ nhớ, bất kể bạn có sử dụng GC hay không. Việc thực thi GC tốt nhất mua cho bạn là hầu hết thời gian bạn có thể không đủ khả năng để suy nghĩ về phân bổ bộ nhớ. Tuy nhiên không có bộ cấp phát bộ nhớ cuối cùng. Đối với một cái gì đó quan trọng, bạn phải nhận thức được làm thế nào bộ nhớ được quản lý, và điều này ngụ ý biết làm thế nào mọi thứ được thực hiện trong nội bộ. Điều này đúng với GC và cho phân bổ heap thủ công như nhau.

một số GC cung cấp đảm bảo thời gian thực. "Thời gian thực" không có nghĩa là "nhanh", điều đó có nghĩa là thời gian phản hồi của bộ cấp phát có thể bị giới hạn. Đây là loại bảo đảm cần thiết cho các hệ thống nhúng như các hệ thống điều khiển các lệnh điện trong một mặt phẳng. Kỳ lạ là đủ, để đảm bảo thời gian thực với các nhà sưu tập rác dễ dàng hơn so với các bộ phân bổ thủ công.

GC trong triển khai .NET hiện tại là không thời gian thực; chúng hiệu quả và nhanh chóng về mặt heuristically. Lưu ý rằng cùng có thể nói về phân bổ thủ công với malloc() trong C (hoặc new trong C++) vì vậy nếu bạn sau khi đảm bảo thời gian thực, bạn đã cần phải sử dụng một cái gì đó đặc biệt. Nếu bạn không, sau đó tôi không muốn bạn thiết kế các thiết bị điện tử nhúng cho những chiếc xe và máy bay tôi sử dụng!

5

Tôi có thể cho bạn biết về một số vấn đề tôi gặp phải với bộ thu gom rác của .NET.

Nếu bạn đang chạy ứng dụng sử dụng GC máy chủ (ví dụ: ứng dụng ASP.NET) thì độ trễ của bạn sẽ thực sự là khủng khiếp, với khoảng dừng khoảng một giây khi không có chủ đề nào của bạn có thể thực hiện bất kỳ tiến trình nào tất cả các. Điều này là do .NET 4 server GC là một GC dừng lại. Rõ ràng, .NET 4.5 sẽ giới thiệu GC máy chủ chủ yếu đầu tiên của Microsoft.

Tôi đã từng viết một số mã cụ thể để đo độ trễ trong hệ thống đồng thời sử dụng các bộ sưu tập tích hợp như ConcurrentBag và tiếp tục hết bộ nhớ trong 32 bit do phân mảnh đống lớn vì .NET GC không chống phân mảnh đối tượng lớn . Tôi đã phải thay thế các cấu trúc dữ liệu dựa trên mảng với các cấu trúc dữ liệu hoàn toàn chức năng được phân tán thành hàng triệu mẩu nhỏ để tránh có bất cứ thứ gì trên Heap đối tượng lớn (LOH) gây ra sự phân mảnh.

Tôi đã tìm thấy lỗi trong GC như this one làm cho GC bị rò rỉ bộ nhớ cho đến khi tất cả bộ nhớ hệ thống bị cạn kiệt trong khi vùng heap bị xóa trong một chu kỳ GC lớn không chỉ dừng lại ở tất cả các chuỗi của bạn bởi vì hệ thống đã chuyển đổi) trong tối đa vài phút!

Mặc dù có cài đặt "độ trễ thấp" trong .NET GC mới nhất nhưng thực tế nó chỉ tắt bộ sưu tập rác, vì vậy chương trình của bạn sẽ rò rỉ bộ nhớ cho đến khi bạn nhận được một tạm dừng GC lớn. Microsoft dường như thích cách giải quyết như thế này tương đương với việc nói "viết bộ thu gom rác của riêng bạn nếu bạn muốn độ trễ có thể sử dụng".

Tuy nhiên, .NET GC nói chung rất tốt và khi được sử dụng cẩn thận, bạn có thể nhận được kết quả tốt từ nó. Ví dụ, gần đây tôi đã viết một máy chủ có khả năng chịu lỗi đạt được độ trễ trung bình của 114µ đến cửa với 95% độ trễ dưới 0,5ms. Đó là ấn tượng gần với nhà nước-of-the-nghệ thuật (xem herehere) cho rằng tôi đã viết toàn bộ nền tảng trong F # của bản thân mình chỉ trong một vài tháng. Mạng thực sự đóng góp nhiều hơn vào độ trễ so với .NET GC.

+0

Thats một số đọc thú vị, cảm ơn! Tôi cũng sẽ đọc các liên kết bạn đăng lên :) –

+1

Tôi có thể xác nhận rằng 'SustainedLowLatency' thực sự chỉ tắt GC. Đây thực sự là một cú sốc, sau khi tôi nhận được 'OutOfMemoryException' nhưng trên toàn bộ nó lại hoạt động tốt vì tôi hầu như không có độ trễ khi tôi cần nó, nhưng có thể chịu đựng được tạm dừng vài phút một lần. Sau đó tôi chuyển trở lại 'Đồng thời' và để xóa sạch GC trước khi tắt nó lần nữa. – codekaizen