2016-09-02 19 views
5

Giả sử chúng ta có một chương trình như thế này:Java có thể thu thập các biến trước khi kết thúc phạm vi không?

void main() { 
    // Point 0 
    BigThing bt = new BigThing(); 
    // Point 1 
    WeakReference<BigThing> weak = new WeakReference<>(bt); 
    // Point 2 
    doSomething(weak); 
    // Point 3 
} 

void doSomething(...) { ... } 

Chúng ta biết rằng các tài liệu tham khảo yếu đến đối tượng BigThing không thể ngăn chặn các đối tượng bị thu rác khi nó trở nên không còn mạnh mẽ thể truy cập.

Câu hỏi của tôi là về biến cục bộ bt là tham chiếu mạnh mẽ đối tượng BigThing. Đối tượng có trở nên không thể tiếp cận mạnh tại điểm 2 (ngay trước khi gọi doSomething()) hoặc tại điểm 3 (kết thúc phạm vi khối) không?

Câu trả lời cho câu hỏi này sẽ ảnh hưởng đến việc cuộc gọi đến doSomething() được đảm bảo có thể truy cập đối tượng trực tiếp BigThing hay không.

Tôi không chắc chắn vì bạn có thể tranh luận rằng sau điểm 2, biến cục bộ bt không bao giờ được đọc hoặc viết nữa, do đó biến bị chết hiệu quả và giá trị con trỏ có thể bị loại bỏ. "Tối ưu hóa" này sẽ hợp lệ nếu tất cả các tham chiếu đều mạnh mẽ, nhưng lý do bị tách rời khi các khái niệm về các tham chiếu mềm, yếu, và ma được giới thiệu và các trình kết thúc. Cũng giống như một sự tương tự, bởi vì C++ có các hàm hủy, một giá trị phải được hủy ở cuối phạm vi và không thể được di chuyển về phía trước đến thời điểm sử dụng cuối cùng.

+1

Trong Java, “phạm vi” là một tạo phẩm thời gian biên dịch và không ảnh hưởng đến bộ thu gom rác tại thời gian chạy theo bất kỳ cách nào. – Holger

Trả lời

3

Tôi có thể nói đối tượng là thể thu hồi tại điểm 2, đi bằng ngôn ngữ sau trong JLS section 12.6.1:

Tối ưu hóa biến đổi của một chương trình có thể được thiết kế làm giảm số lượng các đối tượng mà có thể truy cập được ít hơn những người ngây thơ được coi là có thể tiếp cận được. Ví dụ: trình biên dịch Java hoặc trình tạo mã có thể chọn đặt biến hoặc tham số sẽ không còn được sử dụng để rỗng để khiến bộ nhớ cho đối tượng như vậy có khả năng thu hồi sớm hơn.

Vì biến số bt sẽ không còn được sử dụng sau điểm 2, Java được tự do xóa biến đó, khiến đối tượng BigThing chỉ có thể truy cập yếu.

+1

"Tôi sẽ nói" hơi quá khiêm tốn, tôi nghĩ vậy. Điều này rõ ràng gọi ra chính xác kịch bản của OP. Tốt tìm! – yshavit

+0

@ user2357112 Tôi hiểu câu trả lời của bạn, nhưng nếu chúng tôi biên dịch với thông tin gỡ lỗi, thì nó không làm tối ưu hóa, tôi có nghĩa là nếu chúng ta gỡ lỗi luồng mã này đặt điểm ngắt sau điểm 2, chúng ta sẽ có thể đánh giá giá trị được giới thiệu bởi bt? – hunter

+1

@hunter: Tôi không nghĩ rằng JLS thực hiện bất kỳ đề cập đến debuggers, và tôi không nghĩ rằng nó đảm bảo bất cứ điều gì về những gì tối ưu hóa hiệu ứng bạn có thể nhìn thấy nếu bạn chạy mã của bạn dưới một trình gỡ lỗi. Những gì bạn sẽ thấy trong trình gỡ rối là tùy thuộc vào việc triển khai. – user2357112

2

Java 9 giới thiệu Reference.reachabilityFence để giải quyết trường hợp này, điều này tất nhiên cũng ngụ ý rằng nó tồn tại ngay từ đầu.

+1

Ooh, đẹp quá!Tôi đã tự hỏi nếu có một cách tốt để trì hoãn việc hoàn thành một đối tượng, và có vẻ như một cách tốt đang đến. – user2357112

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