2011-01-12 22 views
5

Mặc dù tôi nghĩ rằng tôi hiểu ý chính của vấn đề (tức là một bài hát GC tốt đối tượng, không phải phạm vi), tôi không biết đủ về chủ đề để thuyết phục người khác.Tại sao RAII và bộ sưu tập rác thải loại trừ lẫn nhau?

Bạn có thể cho tôi giải thích về lý do tại sao không có ngôn ngữ được thu gom rác thải với destructistic destrinistic?

+0

-1 Câu hỏi là sai. Có các ngôn ngữ được thu thập rác với các destructistic xác định, ví dụ: 'IDisposable' trên .NET cung cấp sự hủy diệt xác định cho C#, VB.NET và F #. –

Trả lời

3

Chúng KHÔNG loại trừ lẫn nhau. Hãy sử dụng C++ với libgc (bộ sưu tập Boehm-Reiser-Detlefs). Bạn vẫn có thể sử dụng RAII, con trỏ thông minh và xóa thủ công, nhưng với GC đang chạy, bạn cũng có thể "quên" để xóa một số đối tượng.

@ Câu trả lời của Andy về các tài nguyên bị xử lý quá trễ bỏ lỡ điểm quan trọng: đó không phải là sự chậm trễ phát hành tài nguyên rất quan trọng về mặt ngữ nghĩa, mà là thứ tự phát hành.

Lý do GC có xu hướng không đặt hàng phát hành tốt là nó sẽ yêu cầu một loại topo về yêu cầu đặt hàng (phụ thuộc) và đó là một thuật toán đắt tiền.

Tuy nhiên Ocaml GC có một cơ sở thú vị nơi bạn có thể đính kèm một finaliser cho một đối tượng. Nếu đối tượng trở nên không thể kết nối, finaliser được chạy, tuy nhiên đối tượng không bị xóa (vì finaliser có thể làm cho nó có thể truy cập được nữa: trong trường hợp đó bạn thậm chí có thể đính kèm một finaliser). Những finalisers có thể cung cấp một số kiểm soát đặt hàng.

+0

Thứ tự phát hành có thể là quan trọng. Nhưng một sự chậm trễ không xác định để phát hành, và có thể thất bại hoàn toàn để phát hành, cũng có thể là quan trọng. Nó không phải là một trong hai hoặc cả hai và. –

+0

Một sự chậm trễ không xác định để phát hành thực sự có thể là quan trọng, bao gồm phát hành bộ nhớ! Hiệu suất vấn đề. Nhưng nó không liên quan đến ngữ nghĩa. Tuy nhiên, hoàn toàn thất bại trong việc giải phóng, không thành vấn đề, nhưng nó không thể xảy ra nếu GC được chạy tại điểm kết thúc. Đối với một số tài nguyên như xử lý tập tin trên Unix có xu hướng không chạy GC trên chấm dứt bởi vì hệ điều hành sẽ phát hành các nguồn tài nguyên dù sao đi nữa. Lời khuyên chung khi sử dụng GC là KHÔNG sử dụng RAII cho các tài nguyên quan trọng, được phát hành dưới sự kiểm soát của chương trình. Tuy nhiên nó không rõ ràng điều đó có nghĩa là với đánh giá lười biếng ví dụ như trong Haskell. – Yttrill

0

Từ Wikipedia, sau khi lưu ý rằng truy tìm người thu gom rác là loại phổ biến nhất:

Tracing thu gom rác thải không phải là xác định. Một đối tượng trở thành đủ điều kiện thu gom rác thải sẽ thường được dọn sạch cuối cùng, nhưng không có đảm bảo khi (hoặc thậm chí nếu) điều đó sẽ xảy ra.

Do đó, dựa vào RAII có thể dẫn đến tài nguyên bị xử lý quá muộn.

Kết quả là, ví dụ, Java có một hướng dẫn để "tránh finalizers" (mục 6 trong "Java hiệu quả" của Josua Bloch). "Không có thời gian quan trọng bao giờ nên được thực hiện trong một finalizer."

+0

FWIW Trang Wikipedia về thu gom rác thải phần lớn là sai, kể cả phần đó. –

+0

@JonHarrop - Bất kỳ lời chỉ trích cụ thể nào của câu trả lời này đều được hoan nghênh. –

+0

Rõ ràng là hành động của một thuật toán GC đơn giản là hoàn toàn xác định trong một ứng dụng đơn luồng. Nó có thể hoặc có thể không khó dự đoán, nhưng hệ thống của tôi ít nhất có một cuộc gọi thu thập rõ ràng() chạy GC và sẽ chạy finalisers. Tính quyết định chỉ bị mất trong các ứng dụng đa luồng, có thể có bất kỳ định nghĩa không ràng buộc hoặc không bị ràng buộc nào (tùy thuộc vào hệ thống và ứng dụng), vì vậy không rõ ràng ngay cả trong trường hợp đó GC làm mọi thứ tồi tệ hơn chúng. – Yttrill

0

Bộ thu gom rác không thể chạy mọi lúc (việc đếm ngược trở nên gần hơn, nhưng thường không được tính là bộ sưu tập rác), vì vậy nó thậm chí không thử. Đó là đồng bằng không thực tế. Do đó, có sự chậm trễ không thể tránh khỏi giữa một đối tượng trở nên không thể truy cập được (ví dụ: vì tham chiếu duy nhất nằm ngoài phạm vi) và GC thu thập nó, có thể kích hoạt trình hoàn thiện. Sự chậm trễ này không xác định ... trừ khi (và sau đó, hủy diệt xác định theo nghĩa hẹp nhất của từ là có thể, mặc dù vẫn không thực tế) buộc GC vào một lịch xác định - nhưng điều này khá gần với "GC chạy mọi lúc" , điều này vẫn vô cùng phi thực tế.

Vì vậy, GC và xóa sạch xác định là loại trừ lẫn nhau vì GC thực hiện tất cả việc dọn dẹp và không thể đủ khả năng xác định nhưng phải dựa vào tối đa hóa hiệu quả của nó.

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