Tóm lại : Người thu gom rác không sử dụng đệ quy. Họ chỉ kiểm soát theo dõi bằng cách theo dõi về cơ bản hai bộ (có thể kết hợp). Thứ tự truy tìm và xử lý ô là không liên quan, điều này cho phép tự do thực hiện đáng kể để đại diện cho các bộ. Do đó, có nhiều giải pháp thực sự rất rẻ trong việc sử dụng bộ nhớ. Điều này rất cần thiết vì GC được gọi chính xác khi heap hết bộ nhớ. Mọi thứ có một chút khác biệt với những ký ức ảo lớn, vì các trang mới có thể được phân bổ dễ dàng và kẻ thù không thiếu không gian, mà thiếu địa phương dữ liệu
.
Tôi giả sử bạn đang xem xét truy tìm người thu gom rác, không tính tham chiếu mà câu hỏi của bạn dường như không áp dụng.
Câu hỏi tập trung vào chi phí bộ nhớ theo dõi để theo dõi một tập hợp: tập hợp (không được bảo vệ) của các ô nhớ có thể truy cập vẫn chứa con trỏ chưa được theo dõi. Đây chỉ là một nửa vấn đề bộ nhớ
cho bộ sưu tập rác. GC cũng phải theo dõi một tập hợp khác: tập (đã truy cập) của tất cả các ô đã được tìm thấy có thể truy cập được, để lấy lại tất cả các ô khác ở cuối quy trình. Thảo luận về cái này và cái kia không có ý nghĩa hạn chế, vì chúng có thể có chi phí tương tự, sử dụng các giải pháp tương tự và thậm chí được kết hợp.VUV
Điều đầu tiên cần lưu ý là tất cả các dấu vết theo cùng một mô hình trừu tượng, dựa trên sự thăm dò có hệ thống của đồ thị có hướng của các ô trong bộ nhớ có thể truy cập được từ chương trình, trong đó các ô nhớ là các đỉnh và các con trỏ là các cạnh được định hướng. Nó sử dụng cho các bộ sau:
tập (truy cập) của các tế bào đã được tìm thấy để có thể truy cập bởi các mutator , tức là chương trình hay thuật toán mà GC được thực hiện. Tập được phân chia thành hai tập con khác nhau:
;V V = U ∪ TVVV=U∪T
tập hợp (chưa được bảo vệ) của các ô được truy cập với các con trỏ chưa được theo dõi;U
tập (theo dõi) của các ô được truy cập có tất cả các con trỏ của chúng được theo dõi.T
chúng tôi cũng lưu ý tập hợp tất cả các ô trong heap, có sử dụng hay không.H
Chỉ và , hoặc và , cần được biểu diễn bằng cách nào đó để thuật toán hoạt động.U U TVUUT
Thuật toán bắt đầu từ một số con trỏ gốc được biết đến với hệ thống thời gian chạy (thường là các con trỏ trong bộ nhớ được cấp phát ngăn xếp) và đặt tất cả các ô mà chúng trỏ vào tập không được bảo vệ (do đó cũng ở ).VUV
Sau đó, bộ sưu tập lấy các ô trong từng cái một và kiểm tra từng ô tất cả các con trỏ của nó. Đối với mỗi con trỏ, nếu ô nhọn nằm trong , thì không có gì được thực hiện, nếu không thì ô nhọn được thêm vào , vì các con trỏ của nó vẫn chưa được kiểm tra. Khi tất cả các con trỏ của nó đã được xử lý, ô được chuyển từ tập chưa được xử lý sang tập theo dõi .c V U c U TUcVUcUT
Dấu vết chấm dứt khi trống. Điều này chắc chắn sẽ xảy ra, vì không có tế bào nào đi qua hơn một lần. Tại thời điểm đó, và tất cả các ô trong được biết là có thể truy cập được vào chương trình, do đó không thể thu hồi được. bổ sung của trong heap xác định những ô nào không thể truy cập được bằng chương trình trình biến đổi và có thể được người thu thập lấy lại để phân bổ trong tương lai cho trình biến đổi.U V = T V H - V VUUV=TVH−VV
Của couse, các chi tiết khác nhau tùy thuộc vào cách các bộ được thực hiện và tùy thuộc vào đó là và , hay và , được thể hiện một cách hiệu quả.U U TVUUT
Tôi cũng bỏ qua chi tiết về một tế bào là gì, dù chúng có một kích cỡ hay nhiều, cách chúng ta tìm thấy con trỏ trong chúng, cách chúng có thể được nén và một loạt các vấn đề kỹ thuật khác mà bạn có thể tìm thấy trong sách và khảo sát về thu gom rác .
Bạn có thể nhận thấy rằng đây là một thuật toán cực kỳ đơn giản. Không có đệ quy, mà chỉ có một vòng lặp trên các phần tử của tập có thể phát triển khi nó đang được xử lýU , cho đến khi cuối cùng nó trống rỗng. Không có một giả định tiên nghiệm về bộ nhớ thêm.
Bất cứ điều gì cho phép xác định các bộ và thực hiện đủ rẻ các hoạt động cần thiết sẽ làm. Lưu ý rằng thứ tự các ô được xử lý là không liên quan (không cần cụ thể cho ngăn xếp đẩy xuống), điều này mang lại rất nhiều sự tự do cho việc chọn phương tiện để biểu diễn các bộ một cách hiệu quả.
Trường hợp thực hiện được biết khác nhau là trong cách các bộ này được thực sự đại diện. Nhiều kỹ thuật đã thực sự được sử dụng:
bit map: Một số không gian bộ nhớ được giữ lại cho một bản đồ có một bit cho mỗi ô nhớ, có thể được tìm thấy bằng cách sử dụng địa chỉ của ô. Bit được bật khi ô tương ứng nằm trong tập xác định bởi bản đồ. Nếu chỉ sử dụng bản đồ bit, bạn chỉ cần 2 bit cho mỗi ô.
cách khác, bạn có thể có không gian cho một bit thẻ đặc biệt (hoặc 2) trong mỗi ô để đánh dấu nó.
list: bạn tạo một danh sách các ô trong tập hợp. Bạn không cần một ngăn xếp, hoặc một cấu trúc dữ liệu cụ thể. Trong một số hệ thống, kỹ thuật đảo ngược con trỏ sắc sảo cho phép xây dựng danh sách với rất ít bộ nhớ, chính xác là bit trong đó là số con trỏ trên mỗi ô, điều này được giảm thêm bằng cách sắp xếp các bit.plog2pp
bạn có thể kiểm tra một vị ngữ về nội dung của ô và các con trỏ của nó.
bạn có thể định vị lại ô trong một phần bộ nhớ trống dành cho tất cả chỉ các ô thuộc về tập hợp được biểu diễn.
một trường hợp đặc biệt thú vị là có một ô được truy cập được di chuyển trong một vùng bộ nhớ liền kề khác (tìm tập ) và biểu diễn tập của các ô được theo dõi bởi một địa chỉ ranh giới duy nhất, nhưng thay đổi, lớn hơn địa chỉ của các ô trong , và ít hơn so với .T T UVTTU
bạn thực sự có thể kết hợp các kỹ thuật này, ngay cả đối với một bộ duy nhất.
Như đã nói, tất cả những điều trên đã được sử dụng bởi một số người thu gom rác đã triển khai, kỳ lạ như một số có vẻ như. Tất cả phụ thuộc vào các ràng buộc khác nhau của việc thực hiện. Và chúng có thể khá rẻ trong việc sử dụng bộ nhớ, có thể được giúp đỡ bằng cách xử lý các chính sách đơn hàng có thể được tự do lựa chọn cho mục đích đó, vì chúng không quan trọng đối với kết quả cuối cùng.
Những gì có vẻ kỳ lạ nhất, chuyển các tế bào trong một khu vực mới, thực sự rất phổ biến: nó được gọi là bộ sưu tập sao chép. Nó chủ yếu được sử dụng với bộ nhớ ảo.
Rõ ràng không có đệ quy và ngăn xếp thuật toán trình biến đổi không phải sử dụng.
Một điểm quan trọng khác là nhiều GC hiện đại được triển khai cho các bộ nhớ ảo lớn . Sau đó, có được không gian để thực hiện và danh sách bổ sung hoặc ngăn xếp không phải là một vấn đề vì các trang mới có thể được phân bổ dễ dàng. Tuy nhiên, trong những ký ức ảo lớn, kẻ thù không phải là thiếu không gian mà là thiếu địa phương . Sau đó, cấu trúc đại diện cho các bộ và việc sử dụng chúng, phải được hướng tới việc bảo tồn địa phương của cấu trúc dữ liệu và thực hiện GC. Vấn đề không phải là không gian mà là thời gian. Việc triển khai không đầy đủ có nhiều khả năng cho thấy sự chậm chạp không thể chấp nhận hơn là tràn bộ nhớ.
Tôi đã không đưa ra các tài liệu tham khảo cho nhiều thuật toán cụ thể, kết quả từ các kết hợp khác nhau của các kỹ thuật này, vì điều này dường như đủ dài.