2010-08-17 98 views
8

Giả sử tôi có danh sách được liên kết kép. Tôi tạo ra nó như vậy:Câu hỏi về Thu gom rác trong Java

MyList list = new MyList(); 

Sau đó, tôi thêm một số nút, sử dụng nó và sau đó quyết định vứt bỏ danh sách cũ như thế này:

list = new MyList(); 

Kể từ khi tôi vừa tạo ra một danh sách mới, các nút bên trong khu vực bộ nhớ cũ vẫn chỉ vào nhau. Điều đó có nghĩa là khu vực với các nút cũ sẽ không bị thu gom rác? Tôi có cần phải làm cho mỗi điểm nút để null vì vậy họ đang GC'd?

+0

bản sao có thể có của [Trình thu gom rác Java xử lý tự tham khảo như thế nào?] (Http://stackoverflow.com/questions/407855/how-does-java-garbage-collector-handle-self-reference) –

+0

cũng xem : [Tham khảo thông tư trong Java] (http://stackoverflow.com/questions/176745/circular-references-in-java) –

Trả lời

12

Không, bạn không. Java GC xử lý các tham chiếu tuần hoàn tốt.

Về mặt lý thuyết, mỗi lần chạy GC, nó nhìn vào tất cả các tài liệu tham khảo gốc "sống" trong hệ thống:

  • biến địa phương tại mỗi stack frame
  • "này" tài liệu tham khảo trong mọi trường hợp phương pháp ngăn xếp khung
  • hiệu quả, tất cả các biến tĩnh (trong thực tế chúng được thực sự tham chiếu bởi Class đối tượng, đó là lần lượt tham chiếu bởi ClassLoader s, nhưng cho phép bỏ qua cho rằng thời điểm hiện tại.)

Với những đối tượng "đã biết", nó kiểm tra các trường bên trong chúng, thêm vào danh sách. Nó recurses xuống vào những đối tượng tham chiếu, và như vậy, cho đến khi nó được tìm thấy tất cả các đối tượng sống trong hệ thống. Sau đó, rác thu thập mọi thứ mà nó chưa được coi là đang phát trực tiếp.

Các nút được tham chiếu theo chu kỳ của bạn đề cập đến nhau, nhưng không có đối tượng trực tiếp nào đề cập đến chúng, vì vậy chúng đủ điều kiện để thu thập rác.

Lưu ý rằng đây là tổng thể tóm tắt đơn giản về cách trình thu thập rác khái niệm hoạt động. Trong thực tế chúng cực kỳ phức tạp, với các thế hệ, sự nén chặt, các vấn đề tương tranh và tương tự.

-1

Bộ thu gom rác tìm kiếm các đối tượng không được tham chiếu ở bất kỳ đâu. Vì vậy, nếu bạn tạo một đối tượng và bạn mất tham chiếu như ví dụ, bộ thu gom rác sẽ thu thập thông tin này.

0

Không - Java (ít nhất là thường được triển khai) không sử dụng tính tham chiếu, nó sử dụng bộ thu gom rác thực. Điều đó có nghĩa là (về bản chất) khi nó hết bộ nhớ, nó nhìn vào các con trỏ trên ngăn xếp, trong sổ đăng ký, và những nơi khác luôn có thể truy cập được, và "truy tìm" chúng để tìm mọi thứ có thể truy cập từ chúng.

Con trỏ trong các cấu trúc dữ liệu khác như danh sách được liên kết gấp đôi của bạn đơn giản là không quan trọng trừ khi có một số con trỏ bên ngoài (có thể truy cập) dẫn đến chúng.

0

Không, GC sẽ lấy lại chúng bất kỳ cách nào, do đó bạn không cần phải trỏ chúng vào không. Dưới đây là mô tả một đoạn tốt từ JavaWorld article:

Mọi thuật toán thu gom rác phải làm hai điều cơ bản. Trước tiên, nó phải phát hiện các đối tượng rác.Thứ hai, nó phải đòi lại không gian heap được sử dụng bởi các đối tượng rác và làm cho nó có sẵn cho chương trình. Rác phát hiện thường được thực hiện bằng cách xác định bộ rễ và xác định khả năng hiển thị từ gốc . Một đối tượng có thể truy cập nếu có là một số đường dẫn tham chiếu từ các gốc mà theo đó chương trình thực thi có thể truy cập đối tượng. Rễ là luôn có thể truy cập được vào chương trình. Mọi đối tượng có thể truy cập từ các gốc đều được xem là trực tiếp. Đối tượng không thể truy cập được coi là rác, vì chúng không còn có thể ảnh hưởng đến quá trình thực hiện chương trình tương lai .

0

Bộ thu gom rác trông giống như các đối tượng được tham chiếu bởi chuỗi trực tiếp. Nếu các đối tượng không thể truy cập các đối tượng, chúng sẽ đủ điều kiện để thu thập rác.

Nó không quan trọng nếu các đối tượng đang tham chiếu lẫn nhau.

0

Như những người khác đã chỉ ra, trình thu gom rác Java không chỉ đơn giản xem xét tính tham chiếu; thay vào đó, về cơ bản nó nhìn vào một biểu đồ nơi các nút là các đối tượng hiện đang tồn tại và các liên kết là một tham chiếu từ một đối tượng này đến một đối tượng khác. Nó bắt đầu từ một nút được biết là đang sống (ví dụ, phương thức chính) và sau đó rác thu thập bất cứ thứ gì không thể truy cập được.

The Wikipedia article on garbage collection thảo luận về nhiều cách khác nhau có thể thực hiện được, mặc dù tôi không biết chính xác phương pháp nào được sử dụng bởi bất kỳ triển khai JVM nào.

1

Nếu bạn tạo danh sách được liên kết kép của riêng mình và bạn đưa vào danh sách được liên kết kép này Thùng chứa (chứa các mục từ danh sách của bạn); chỉ những thùng chứa đó được liên kết với nhau.

Vì vậy, trong danh sách của bạn, bạn sẽ có đối tượng A chứa trong A '. A 'được liên kết với B' và B 'là một container chứa B vv Và không có đối tượng nào phải tham chiếu đến một đối tượng khác.

Trong trường hợp bình thường, các vùng chứa đó sẽ không có sẵn từ bên ngoài (chỉ nội dung thú vị); do đó chỉ danh sách của bạn sẽ có tham chiếu đến vùng chứa của bạn (hãy nhớ rằng nội dung của bạn không biết về vùng chứa của mình).

Nếu bạn loại bỏ tham chiếu cuối cùng vào danh sách của bạn (danh sách, không phải thùng chứa hay nội dung) GC sẽ cố gắng thu thập nội dung danh sách của bạn, phù thủy là đồ chứa và nội dung của bạn.

Vì vùng chứa của bạn không có sẵn bên ngoài tham chiếu duy nhất mà chúng có là nhau và danh sách chính. Tất cả được gọi là hòn đảo cách ly. Liên quan đến nội dung, nếu họ vẫn có tài liệu tham khảo trong ứng dụng của bạn, họ sẽ tồn tại GC, nếu không họ sẽ không.

Vì vậy, khi bạn xóa danh sách của mình chỉ A 'và B' sẽ bị xóa vì ngay cả khi chúng vẫn có tham chiếu, những tham chiếu đó là một phần của một hòn đảo. Nếu A và B không còn tham chiếu nữa thì chúng cũng sẽ bị xóa.