2012-09-28 38 views
5

Với mã bên dưới.Thu gom rác của các trường riêng tư

class A { 
    private B b; 
    public A() { 
     b = new B(); 
    } 
} 

class Main { 
    public static void main(String[] args) { 
     A a = new A(); // two objects are created (a and b) 
     // <-- is B object, referenced only by private a.b eligible for garbage collection? 
     keepAlive(a); 
    } 
} 

Đối tượng B có thể được thu gom rác sau khi đối tượng A được tạo không?

Trả lời

6

Tôi nghĩ không, bởi vì trường này vẫn có thể được truy cập thông qua phản ánh (sử dụng setAccessible(true)).

Về mặt lý thuyết, trình biên dịch có thể chứng minh rằng lĩnh vực này sẽ không bao giờ được truy cập, và nó sẽ làm cho B đủ điều kiện để thu gom rác thải (từ JLS 12.6.1 Implementing Finalization):

Một đối tượng có thể truy cập bất kỳ đối tượng có thể được truy cập trong bất kỳ tiềm năng tính toán liên tục từ bất kỳ chuỗi trực tiếp nào. Tối ưu hóa các phép biến đổi của một chương trình có thể được thiết kế để giảm số lượng các đối tượng có thể truy cập được ít hơn so với những đối tượng được xem là ngây thơ. Ví dụ, một trình biên dịch hoặc trình tạo mã có thể chọn để đặt một biến hoặc tham số sẽ không còn được sử dụng để null để làm cho việc lưu trữ cho một đối tượng như vậy có khả năng có thể lấy lại sớm hơn.

Nhưng tôi không nghĩ rằng trong các trình biên dịch thực hành và các JVM là rằng thông minh

1

@Kuba Bạn có nghĩa là: có thể trường hợp của lớp B trong lĩnh vực b sơ thẩm a của lớp A được thu gom rác thải ? Không. Trong khi không a không phải là nullb được tham chiếu bởi a.

1

Không, vì chuỗi chính có đường dẫn đến b đến a.

0

Trình biên dịch chuẩn không thông minh.

class A 
{ 
    private Object[] array; 

    public A() 
    { 
     array = new Object[10000000]; 
    } 
} 

public static void main(String[] args) 
{ 
    LinkedList<A> list = new LinkedList<A>(); 
    while (true) 
    { 
     list.add(new A()); 
    } 
} 

Mã này thoát khỏi ngoại lệ bộ nhớ sau một số lượng rất nhỏ vòng lặp, vì vậy câu trả lời cho câu hỏi ban đầu chắc chắn là không.