2010-02-28 34 views
8

Tôi không thể hiểu một vài điều về bộ sưu tập rác.Bộ sưu tập rác

Thứ nhất, không gian được phân bổ dữ liệu như thế nào? tức là trên stack hoặc heap (Theo kiến ​​thức của tôi, tất cả các biến tĩnh hoặc toàn cầu được gán không gian trên stack và biến cục bộ được gán không gian trên heap).

Thứ hai, GC chạy trên dữ liệu trên ngăn xếp hoặc đống? tức là một thuật toán GC như Mark/Sweep sẽ đề cập đến dữ liệu trên stack như là quyền root? Và sau đó ánh xạ tất cả các biến có thể truy cập trên heap bằng cách kiểm tra biến nào trên heap tham chiếu đến tập hợp gốc.

Điều gì xảy ra nếu chương trình không có biến toàn cầu? Thuật toán hoạt động như thế nào?

Kính trọng, thằng nhọ

+2

Bạn có hỏi về một nhà sưu tập nền tảng/thu gom rác cụ thể không? Vui lòng chỉnh sửa thẻ và/hoặc câu hỏi của bạn để cụ thể hơn. – Jay

+0

Điều đó nói chung ... Nói về tham chiếu đến liên kết wikipedia: http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29 –

Trả lời

11

Nó có thể giúp làm sáng tỏ những gì nền tảng của GC bạn đang hỏi về - JVM, CLR, Lisp, vv Điều đó nói rằng:

Đầu tiên để lùi lại một bước, các biến địa phương nhất định thường được phân bổ trên ngăn xếp. Tuy nhiên, các chi tiết cụ thể có thể khác nhau tùy theo ngôn ngữ. Để lấy C# làm ví dụ, chỉ có các thông số Value Types cục bộ và được lưu trữ trên ngăn xếp. Vì vậy, trong C#, foo sẽ được cấp phát trên stack:

public function bar() { 
    int foo = 2; 
    ... 
} 

Ngoài ra, các biến được cấp phát động sử dụng bộ nhớ từ đống. Điều này nên trực giác có ý nghĩa, nếu không thì ngăn xếp sẽ phải phát triển năng động mỗi khi một số new được gọi. Ngoài ra, nó sẽ có nghĩa là các biến như vậy chỉ có thể được sử dụng như là người dân địa phương trong hàm cục bộ đã phân bổ chúng, tất nhiên là không đúng bởi vì chúng ta có thể có (ví dụ) các biến thành viên lớp. Vì vậy, để lấy một ví dụ khác từ C#, trong trường hợp sau đây result được cấp phát trên heap:

public class MyInt 
{   
    public int MyValue; 
} 

... 
MyInt result = new MyInt(); 
result.MyValue = foo + 40; 
... 

Bây giờ với nền ý nghĩ đó, bộ nhớ trên đống là thu gom rác. Bộ nhớ trên ngăn xếp không cần GC vì bộ nhớ sẽ được phục hồi khi hàm hiện tại trả về. Ở cấp độ cao, thuật toán GC hoạt động bằng cách theo dõi tất cả các đối tượng được phân bổ động trên heap. Sau khi được phân bổ qua new, đối tượng sẽ được theo dõi bởi GC và được thu thập khi đối tượng không còn trong phạm vi và không có thêm tham chiếu đến đối tượng đó.

+0

Cảm ơn bạn rất nhiều. Điều này làm cho mọi việc dễ hiểu hơn nhiều để hiểu được –

+0

"Để lấy C#, chỉ các Loại Giá trị được lưu trữ trên ngăn xếp". - điều này không đúng. Trích dẫn "C# In Depth", trang 52: "... giá trị của biến tồn tại khi nó được khai báo - vì vậy nếu bạn có lớp aa với biến mẫu int, giá trị của biến này cho bất kỳ đối tượng nào sẽ luôn là nơi còn lại dữ liệu cho đối tượng là - trên heap ... Chỉ có các biến cục bộ và tham số phương thức trực tiếp trên ngăn xếp ... " – duffymo

+1

Phải, tôi có nghĩa là chỉ các biến cục bộ là Loại giá trị mới được lưu trữ trên ngăn xếp. Tôi sẽ cập nhật câu trả lời để làm rõ hơn ... –

2

Thứ nhất, không gian được phân bổ dữ liệu như thế nào? tức là trên chồng hoặc đống (Theo số kiến ​​thức của tôi, tất cả các biến số tĩnh hoặc toàn cầu được gán khoảng trống trên ngăn xếp và biến cục bộ được gán không gian trên heap).

Không, biến ngăn xếp là cuộc gọi phương thức và biến cục bộ. Một khung ngăn xếp được tạo ra khi phương thức được gọi và xuất hiện khi nó được trả về.

Bộ nhớ trong Java và C# được cấp phát trên heap bằng cách gọi "mới".

Thứ hai, GC chạy trên dữ liệu trên ngăn xếp hoặc đống? tức là một thuật toán GC như Đánh dấu/quét sẽ tham chiếu đến dữ liệu trên ngăn xếp dưới dạng tập hợp gốc đúng không?Và sau đó ánh xạ tất cả các biến có thể truy cập trên heap bằng cách kiểm tra biến nào trên heap tham chiếu vào bộ gốc.

GC được sử dụng trên heap.

Đánh dấu và quét sẽ không được coi là thuật toán GC cắt cạnh. Cả Java và .NET GC đều sử dụng các mô hình thế hệ.

Điều gì xảy ra nếu chương trình không có biến số toàn cầu ? Thuật toán sau đó như thế nào?

"Biến toàn cầu" có nghĩa là gì trong các ngôn ngữ như Java và C# nơi mọi thứ thuộc về một lớp học?

Gốc của đồ thị đối tượng là tùy ý. Tôi sẽ thừa nhận rằng tôi không biết nó được chọn như thế nào.

+0

Cảm ơn bạn rất nhiều .. điều đó giải thích rất nhiều cho tôi. –

1

Đọc this article. Đây là một cuộc khảo sát rất tốt về các kỹ thuật thu gom rác chưa xử lý. Nó sẽ cung cấp cho bạn sự hiểu biết cơ bản và thuật ngữ về GC. Sau đó, theo dõi với cuốn sách Jones và Lins "Bộ sưu tập rác: Thuật toán cho quản lý bộ nhớ động tự động". Trái ngược với bài viết khảo sát tôi chỉ ra ở trên, cuốn sách không có sẵn miễn phí trên Web; Bạn phải mua nó; Nhưng nó là giá trị nó.

0

Bạn có thể tìm thấy các bản tóm tắt ngắn Garbage Collection on the Memory Management Reference hữu ích.

Cuối cùng, việc thu thập rác phải bắt đầu tại sổ đăng ký của bộ xử lý, vì bất kỳ đối tượng nào không thể truy cập được bởi bộ xử lý đều có thể được tái chế. Tùy thuộc vào ngôn ngữ và hệ thống thời gian chạy, nó có ý nghĩa để giả định tĩnh rằng ngăn xếp và thanh ghi của chủ đề cũng có thể truy cập, cũng như "biến toàn cầu".

Ngăn xếp có thể giúp bạn nhận các biến cục bộ. Vì vậy, trong các GC đơn giản, bạn bắt đầu bằng cách quét các ngữ cảnh chủ đề, các ngăn xếp của chúng và các biến toàn cầu. Nhưng điều đó chắc chắn không đúng trong mọi trường hợp. Một số ngôn ngữ không sử dụng ngăn xếp hoặc có các biến toàn cục như vậy. Hơn nữa, GC có thể sử dụng barrier để họ không phải xem từng ngăn xếp hoặc toàn cầu mỗi lần. Một số phần cứng chuyên dụng, chẳng hạn như Symbolics Lisp Machine có các rào cản đối với thanh ghi!

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