Có thể hơi muộn, nhưng lời giải thích hiện tại hoàn toàn không đạt yêu cầu đối với tôi và tôi nghĩ rằng tôi đã có một giải thích hợp lý hơn.
Trước hết, mọi GC thực hiện một số loại truy tìm từ bộ gốc theo cách này hay cách khác. Điều này có nghĩa rằng nếu người đứng đầu cũ được thu thập, chúng tôi sẽ không đọc biến số next
dù sao đi nữa - không có lý do gì để làm như vậy. Do đó NẾU đầu được thu thập trong lần lặp tiếp theo, điều đó không quan trọng.
IF trong câu trên là phần quan trọng ở đây. Sự khác biệt giữa thiết lập bên cạnh thứ gì đó khác nhau không quan trọng đối với việc thu thập chính nó, nhưng có thể tạo sự khác biệt cho các đối tượng khác.
Giả sử một GC thế hệ đơn giản: Nếu đầu nằm trong tập hợp trẻ, nó sẽ được thu thập trong GC tiếp theo dù sao đi nữa. Nhưng nếu nó ở trong bộ cũ, nó sẽ chỉ được thu thập khi chúng ta thực hiện một GC đầy đủ, điều hiếm khi xảy ra.
Vậy điều gì sẽ xảy ra nếu đầu nằm trong nhóm cũ và chúng tôi làm một GC trẻ?Trong trường hợp này JVM giả định rằng mọi đối tượng trong heap cũ vẫn còn sống và thêm mọi tham chiếu từ cũ sang các đối tượng trẻ vào bộ gốc cho GC trẻ. Và đó chính là điều mà nhiệm vụ tránh ở đây: Viết vào heap cũ thường được bảo vệ bằng hàng rào viết hoặc thứ gì đó để JVM có thể nắm bắt các nhiệm vụ đó và xử lý chúng một cách chính xác - trong trường hợp của chúng tôi, nó xóa đối tượng next
được trỏ đến từ bộ gốc mà không có hậu quả.
Ví dụ ngắn:
Giả sử chúng tôi có 1 (old) -> 2 (young) -> 3 (xx)
. Nếu chúng tôi xóa 1 và 2 ngay từ danh sách của mình, chúng tôi có thể mong đợi rằng cả hai yếu tố sẽ được thu thập bởi GC tiếp theo. Nhưng nếu chỉ có một GC trẻ xảy ra và chúng tôi đã không loại bỏ các con trỏ next
trong cũ, cả hai yếu tố 1 và 2 sẽ không được thu thập. Trái ngược với điều này nếu chúng tôi đã loại bỏ các con trỏ trong 1, 2 sẽ được thu thập bởi các GC trẻ ..
có thể nhận xét là đã lỗi thời (bạn có thể tìm thấy sự kiểm soát phiên bản và theo dõi các bình luận cho cam?) :) – milan
Thật thú vị rằng đây var tạm thời và bình luận được thêm vào chỉ trong java 7. Vì vậy, nó đã được definitively bởi một số ý định. Xem http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/LinkedBlockingQueue.java#LinkedBlockingQueue.extract%28%29 và http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/concurrent/LinkedBlockingQueue.java#LinkedBlockingQueue.dequeue%28%29 – Vadzim
đó là openjdk, LinkedBlockingQueue trong Oracle jdk 6 trên máy Mac (1.6.0_29-b11-402.jdk) có biến tạm thời. – milan