2017-03-05 39 views
6

Trong khi thu thập bộ nhớ thế hệ trẻ, bộ thu JVM chỉ quét các đối tượng gốc đó (truy nhập trực tiếp từ bộ gốc) thuộc về thế hệ trẻ và cũng sử dụng ghi hàng rào được hỗ trợ thẻ bảng/nhớ đặt để xác định khu vực của thế hệ cũ mà có thể có thể chứa các đối tượng có chứa tài liệu tham khảo cho các đối tượng trong thế hệ trẻ.Thu thập rác JVM - truy tìm các đối tượng trực tiếp trong thế hệ trẻ

Câu hỏi mà tôi có là nếu người thu trẻ xác định rằng một đối tượng cụ thể trong thế hệ trẻ chỉ có một tham chiếu bên ngoài từ một đối tượng trong thế hệ cũ, . không rác và do đó làm cho các đối tượng thế hệ trẻ 'sống' và không đủ điều kiện để thu thập? Ví dụ, có thể có một đường dẫn từ gốc đặt trực tiếp đến đối tượng này trong thế hệ cũ mà lần lượt có một tham chiếu đến đối tượng thế hệ trẻ đã nói. Nhà sưu tập trẻ thường xem xét đối tượng thế hệ trẻ này là sống hay làm thế nào để xác định liệu đối tượng thế hệ cũ trỏ đến nó là trực tiếp/rác trước khi quyết định bỏ qua/thu thập nó?

Trả lời

4

làm cách nào để biết liệu chính đối tượng thế hệ cũ không phải là rác?

Nó không phải là một bộ sưu tập lớn/đầy đủ. Giả định là đối tượng gen cũ không chết thường xuyên.

Khi một bộ sưu tập đầy đủ được thực hiện, nó sẽ kiểm tra tất cả các đối tượng, nhưng khi một bộ sưu tập nhỏ/trẻ được thực hiện chỉ các đối tượng trong bộ sưu tập trẻ được làm sạch.

+0

Cảm ơn bạn đã trả lời - Tôi ít quan tâm đến bộ sưu tập của đối tượng thế hệ cũ nhưng sự sống còn/bộ sưu tập của đối tượng thế hệ trẻ trong một GC trẻ. Vì vậy, nếu tôi hiểu chính xác từ những gì bạn nói, nếu chúng ta có một đối tượng thế hệ trẻ chỉ có một tham chiếu đến từ một đối tượng thế hệ cũ mà chính nó là rác, vật thể thế hệ trẻ này (là rác) sống sót sau các GC trẻ và chỉ được thu thập trong GC trẻ đầu tiên xảy ra sau khi GC chính thu thập đối tượng thế hệ cũ đã nói. – Stormshadow

+0

Sự hiểu biết của tôi có đúng không? – Stormshadow

+1

Về cơ bản có. Tôi nghĩ rằng thế hệ "Đầy đủ" liên quan đến một bộ sưu tập của cả không gian trẻ và cũ cùng một lúc, bởi vì "tại sao không" và cũng bởi vì bạn cũng cần phải đánh dấu từ rễ và thông qua các đối tượng trong thế hệ trẻ để tìm tất cả đối tượng thế hệ cũ. Vì vậy, bạn có thể chỉ đơn giản là nó để "những đối tượng sẽ không được thu thập cho đến khi gc đầy đủ tiếp theo". @Stormshadow – BeeOnRope

1

Câu hỏi đặt ra là “làm thế nào để bạn có thể một kịch bản như vậy?”

Để tạo một tham chiếu từ một đối tượng cũ sang một đối tượng thanh niên, đối tượng cũ phải thể truy cập, vì nếu không chúng ta không thể lưu trữ một tham chiếu đến đối tượng trẻ trong đó. Để trở thành không thể truy cập sau đó, chúng ta phải sửa đổi ít nhất một trong hai, một tham chiếu gốc hoặc một đối tượng cũ mà trước đây đã tham chiếu đối tượng cũ đang được đề cập đến. Như bạn đã đề cập, các kiểu ghi này được JVM theo dõi, điều quan trọng, như để phát hiện rằng một đối tượng cũ giờ đây tham chiếu đến một đối tượng trẻ, nó phải biết rằng vùng bộ nhớ của đối tượng cũ (aka card) đã được sửa đổi. Về nguyên tắc, kể từ khi đánh dấu thẻ cũng ngụ ý ghi nhớ các tài liệu tham khảo đến, gc là bây giờ có khả năng phát hiện rằng các đối tượng cũ trở nên không thể truy cập, ngay cả khi không có một gc lớn. Nó chỉ phải xem xét các thẻ sửa đổi (hoặc bộ gốc) để tìm hiểu về nó. Cho dù có, phụ thuộc vào các yếu tố môi trường, như thuật toán gc đã chọn, tức là bạn sử dụng CMS (không) hoặc G1 (có thể) và cách "cấu hình hỗn hợp" được định cấu hình hoặc áp lực bộ nhớ thực tế.

Tất nhiên, nếu bạn sử dụng bộ thu đồng thời, có khả năng sửa đổi sẽ làm cho đối tượng cũ không thể truy cập được trong khi chu trình thu thập đang diễn ra. Trong tình huống này, có thể là đối tượng trẻ được coi là có thể truy cập trong chu kỳ gc này, ngay cả khi nó không phải là nếu sửa đổi xảy ra chỉ một nano giây trước đó.

+0

Tôi không theo dõi cách hoạt động của nó. Trong khi đúng là viết mà làm cho một đối tượng cũ không thể truy cập sẽ bị bắt bởi dấu, bộ sưu tập trẻ không thể sử dụng thông tin đó để chứng minh rằng bất kỳ đối tượng gen cụ thể nào là không thể truy cập được: để làm điều đó cần phải làm một dấu hiệu đầy đủ của toàn bộ gen cũ, để hiểu hiệu quả cuối cùng thực tế của _all_ ghi cho gen cũ kể từ khi thu thập cuối cùng. Về cơ bản nó sẽ phải làm một gc đầy đủ. – BeeOnRope

+0

Hãy suy nghĩ về việc đánh dấu thẻ như một lý thuyết bảo thủ: nó có khả năng _conservatively_ tăng sự gia tăng bộ tiếp cận khi nó nhận thấy một tham chiếu đến một đối tượng trẻ đã được viết vào gen cũ. Điều này không phải lúc nào cũng đúng - bởi vì nó không thể chắc chắn rằng đối tượng gen cũ thậm chí còn có thể truy cập được, nhưng ít nhất nó là chính xác vì một tập hợp có thể truy cập quá lớn là OK. Mặt khác, nó không thể giảm một cách an toàn các thiết lập có thể truy cập, vì thay đổi đó sẽ phải chính xác và chỉ biết một tham chiếu thay đổi không giúp bạn ở đó. – BeeOnRope

+0

@BeeOnRope: tất nhiên, điều này đòi hỏi một bộ sưu tập * hỗn hợp *, kết hợp các thẻ đã thay đổi. Vì trong kịch bản giả định của OP, chỉ có một tham chiếu gốc duy nhất cho đối tượng cũ và các tham chiếu đến * được ghi nhớ cho một vùng, có thể phát hiện rằng tham chiếu mở rộng vùng đơn này đã biến mất. Vì vậy, chỉ có khu vực phải được đi qua để tìm ra rằng không có tài liệu tham khảo trong khu vực còn lại. Tôi không nói rằng một bộ sưu tập trẻ là đủ, tôi chỉ nói rằng bạn không cần một gc đầy đủ. – Holger

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