Tóm lại
Hoàn thiện không phải là vấn đề đơn giản để xử lý bởi người thu gom rác. Nó rất dễ sử dụng với tính toán tham chiếu GC, nhưng họ GC này thường không đầy đủ, đòi hỏi phải rò rỉ bộ nhớ bằng cách kích hoạt rõ ràng sự phá hủy và hoàn thiện một số đối tượng và cấu trúc. Truy tìm bộ thu gom rác hiệu quả hơn nhiều, nhưng chúng khiến việc xác định và hủy bỏ đối tượng khó khăn hơn nhiều, trái ngược với việc chỉ xác định bộ nhớ không sử dụng, do đó đòi hỏi phải quản lý phức tạp hơn, tốn thời gian và không gian, và phức tạp việc thực hiện.
Giới thiệu
Tôi giả định rằng những gì bạn đang hỏi là tại sao các ngôn ngữ được thu gom rác không tự động xử lý việc hủy / hoàn thiện trong quy trình thu gom rác, như được nêu trong nhận xét:
Tôi thấy rất thiếu khi các ngôn ngữ này coi bộ nhớ là tài nguyên duy nhất đáng để quản lý. Điều gì về ổ cắm, xử lý tập tin, trạng thái ứng dụng?
Tôi không đồng ý với câu trả lời được chấp nhận bởi kdbanman . Mặc dù các sự kiện đã nêu hầu hết là chính xác, mặc dù rất thiên về việc đếm tham chiếu, tôi không tin rằng họ giải thích chính xác tình huống phàn nàn trong câu hỏi.
Tôi không tin rằng thuật ngữ được phát triển trong câu trả lời đó là vấn đề lớn, và nó có nhiều khả năng gây nhầm lẫn. Thật vậy, như đã trình bày, thuật ngữ chủ yếu được xác định theo cách các thủ tục được kích hoạt chứ không phải bởi những gì họ làm. Vấn đề là trong mọi trường hợp, cần phải hoàn thiện một đối tượng không còn cần thiết với một số quy trình dọn dẹp và để giải phóng bất kỳ tài nguyên nào nó đã sử dụng, bộ nhớ chỉ là một trong số đó. Lý tưởng nhất, tất cả nên được thực hiện tự động khi đối tượng không còn được sử dụng, bằng phương tiện của bộ thu gom rác. Trong thực tế, GC có thể bị thiếu hoặc có thiếu sót, và điều này được bù đắp bằng cách kích hoạt rõ ràng bằng chương trình hoàn thiện và khai hoang.
Việc trigerring rõ ràng bởi chương trình là một vấn đề vì nó có thể cho phép khó phân tích lỗi lập trình, khi một đối tượng vẫn đang sử dụng đang bị chấm dứt rõ ràng.
Do đó, tốt hơn nhiều là dựa vào thu gom rác tự động để lấy lại tài nguyên. Nhưng có hai vấn đề:
một số kỹ thuật thu gom rác sẽ cho phép rò rỉ bộ nhớ ngăn chặn việc cải tạo toàn bộ tài nguyên. Điều này nổi tiếng với việc đếm tham chiếu GC, nhưng có thể xuất hiện cho các kỹ thuật GC khác khi sử dụng một số tổ chức dữ liệu mà không cần quan tâm (điểm không được thảo luận ở đây).
trong khi kỹ thuật GC có thể tốt trong việc xác định tài nguyên bộ nhớ không còn được sử dụng, việc hoàn thiện các đối tượng có trong đó có thể không đơn giản và điều đó làm phức tạp vấn đề lấy lại các tài nguyên khác được sử dụng bởi các đối tượng này, thường là mục đích của việc hoàn thiện.
Cuối cùng, một điểm quan trọng thường bị lãng quên là các chu trình GC có thể được kích hoạt bởi bất cứ thứ gì, không chỉ là thiếu bộ nhớ, nếu các móc thích hợp được cung cấp và nếu chi phí của chu trình GC được coi là xứng đáng. Do đó, hoàn toàn ổn khi bắt đầu một GC khi bất kỳ loại tài nguyên nào bị thiếu, với hy vọng giải phóng một số.
Tham khảo đếm người thu gom rác
Đếm tham chiếu là một kỹ thuật thu gom rác yếu , sẽ không xử lý đúng chu kỳ. Nó thực sự sẽ yếu khi phá hủy các cấu trúc lỗi thời và đòi lại các tài nguyên khác đơn giản chỉ vì nó yếu trong việc lấy lại bộ nhớ. Nhưng các công cụ hoàn thiện có thể được sử dụng dễ dàng nhất với bộ thu gom rác tham chiếu (GC), vì một công cụ đếm số ref sẽ lấy lại cấu trúc khi số lượng ref của nó giảm xuống 0, tại thời điểm đó, địa chỉ của nó được biết cùng với loại của nó, hoặc là tĩnh hoặc năng động. Do đó, có thể lấy lại bộ nhớ một cách chính xác sau khi áp dụng bộ hoàn thiện thích hợp và gọi đệ quy quy trình trên tất cả các đối tượng nhọn (có thể thông qua quy trình hoàn thiện).
Tóm lại, việc hoàn thiện rất dễ thực hiện với Ref Counting GC, nhưng bị "không hoàn chỉnh" của GC đó, thực sự là do các cấu trúc hình tròn, chính xác đến mức mà việc phục hồi bộ nhớ phải chịu. Nói cách khác, với số tham chiếu, bộ nhớ được quản lý kém như các tài nguyên khác như ổ cắm, tay cầm tệp, v.v.
Thật vậy, Ref Count GC không có khả năng lấy lại các cấu trúc vòng lặp (nói chung) có thể được xem là rò rỉ bộ nhớ . Bạn không thể mong đợi tất cả các GC để tránh rò rỉ bộ nhớ. Nó phụ thuộc vào thuật toán GC và vào thông tin cấu trúc kiểu có sẵn một cách linh hoạt (ví dụ trong
GC bảo thủ ).
Truy tìm người thu gom rác
Họ GC mạnh hơn, không bị rò rỉ như vậy, là họ truy tìm khám phá các phần sống của bộ nhớ, bắt đầu từ các con trỏ gốc được xác định rõ. Tất cả các phần của bộ nhớ không được truy cập trong quá trình theo dõi này (thực sự có thể bị phân tách theo nhiều cách khác nhau, nhưng tôi phải đơn giản hóa) là những phần không được sử dụng của bộ nhớ có thể được lấy lại 1 . Các bộ sưu tập này sẽ lấy lại tất cả các phần bộ nhớ mà chương trình không thể truy cập được nữa, bất kể nó làm gì. Nó đòi lại các cấu trúc vòng tròn, và GC tiên tiến hơn dựa trên một số biến thể của mô hình này, đôi khi rất tinh vi. Nó có thể được kết hợp với đếm tham chiếu trong một số trường hợp và bù đắp cho điểm yếu của nó.
Một vấn đề là tuyên bố của bạn (ở cuối câu hỏi):
Các ngôn ngữ cung cấp bộ sưu tập rác tự động dường như là ứng cử viên chính để hỗ trợ tiêu hủy / hoàn thiện đối tượng như họ biết chắc chắn 100% khi một đối tượng không còn được sử dụng.
là kỹ thuật không chính xác để truy tìm các nhà sưu tập.
Những gì được biết đến với sự chắc chắn 100% là những phần của bộ nhớ không còn được sử dụng . (Chính xác hơn, nên nói rằng chúng không còn truy cập được nữa , bởi vì một số phần, không còn có thể được sử dụng theo logic của chương trình, vẫn được xem xét sử dụng nếu vẫn còn một con trỏ vô dụng đối với chúng trong chương trình dữ liệu.) Nhưng cần xử lý thêm và các cấu trúc phù hợp để biết những đối tượng không sử dụng có thể đã được lưu trữ trong những phần hiện chưa sử dụng này của bộ nhớ . Điều này không thể được xác định từ những gì đã biết của chương trình, vì chương trình không còn được kết nối với các phần của bộ nhớ.
Do đó, sau khi vượt qua bộ sưu tập rác, bạn chỉ còn lại những mảnh bộ nhớ chứa các đối tượng không còn sử dụng, nhưng không có cách nào để biết những đối tượng này là gì để áp dụng hoàn thiện chính xác. Hơn nữa, nếu trình thu thập dấu vết là loại đánh dấu và quét, thì có thể một số đoạn có thể chứa các đối tượng đã được hoàn thành trong một lần vượt qua trước đó, nhưng không được sử dụng vì lý do phân mảnh. Tuy nhiên điều này có thể được xử lý bằng cách sử dụng gõ rõ ràng mở rộng.
Mặc dù một bộ sưu tập đơn giản sẽ lấy lại những mảnh bộ nhớ này, nhưng không cần phải quảng cáo thêm nữa, việc hoàn thiện đòi hỏi một đường chuyền cụ thể để khám phá bộ nhớ không sử dụng đó, xác định các đối tượng có trong đó và áp dụng các quy trình hoàn thiện. Nhưng một cuộc thăm dò như vậy đòi hỏi phải xác định loại đối tượng được lưu trữ ở đó, và xác định loại cũng là cần thiết để áp dụng hoàn thiện thích hợp, nếu có.
Vì vậy, điều đó bao hàm thêm chi phí trong thời gian GC (vượt qua thêm) và có thể chi phí bộ nhớ thêm để cung cấp thông tin loại thích hợp trong thời gian đó bằng các kỹ thuật đa dạng. Những chi phí này có thể là đáng kể vì người ta thường chỉ muốn hoàn thiện một vài đối tượng, trong khi chi phí không gian và thời gian có thể liên quan đến tất cả các đối tượng.
Một điểm khác là chi phí thời gian và không gian có thể liên quan đến việc thực thi mã chương trình, và không chỉ thực hiện GC.
Tôi không thể đưa ra câu trả lời chính xác hơn, chỉ vào các vấn đề cụ thể, vì tôi không biết chi tiết cụ thể của nhiều ngôn ngữ bạn liệt kê. Trong trường hợp của C, đánh máy là một vấn đề rất khó dẫn đến sự phát triển của các nhà sưu tập bảo thủ. Tôi đoán là điều này cũng ảnh hưởng đến C ++, nhưng tôi không phải là chuyên gia về C ++. Điều này dường như được xác nhận bởi Hans Boehm , người đã thực hiện nhiều nghiên cứu về GC bảo thủ. GC bảo thủ không thể lấy lại chính xác tất cả các bộ nhớ không sử dụng vì nó có thể thiếu thông tin loại chính xác trên dữ liệu. Vì lý do tương tự, nó sẽ không thể áp dụng một cách có hệ thống các quy trình hoàn thiện.
Vì vậy, có thể làm những gì bạn đang yêu cầu, như bạn biết từ một số ngôn ngữ. Nhưng nó không miễn phí. Tùy thuộc vào ngôn ngữ và cách triển khai ngôn ngữ, nó có thể đòi hỏi một chi phí ngay cả khi bạn không sử dụng tính năng này. Các kỹ thuật và sự đánh đổi khác nhau có thể được xem xét để giải quyết các vấn đề này, nhưng điều đó nằm ngoài phạm vi của một câu trả lời có kích thước hợp lý.
1 - đây là một bản trình bày trừu tượng về bộ sưu tập theo dõi (bao gồm cả bản sao và dấu quét và quét), mọi thứ khác nhau tùy theo loại bộ sưu tập theo dõi và khám phá phần không sử dụng của bộ nhớ là khác nhau, tùy thuộc vào việc sao chép hoặc đánh dấu và quét được sử dụng.
finalize
/destroy
là một lời nói dối? Không có gì đảm bảo nó sẽ được thực thi. Và, ngay cả khi, bạn không biết khi nào (được đưa vào bộ sưu tập rác tự động) và nếu bối cảnh cần thiết vẫn còn đó (nó có thể đã được thu thập). Vì vậy, an toàn hơn để đảm bảo trạng thái nhất quán theo các cách khác và người ta có thể muốn buộc lập trình viên làm như vậy.