Does Java GC destroy objects if instance variables still have reference?

后端 未结 4 1910
天命终不由人
天命终不由人 2021-02-07 08:51

I\'ve read through some of the Java garbage collection guides online, but I\'m still a bit unclear and wanted to make sure so that I don\'t have memory leaks in my code.

相关标签:
4条回答
  • 2021-02-07 09:18

    Here is what is going to happen (see comments below)

    // obj1 and obj1.var get created
    SomeObject obj1 = new SomeObject();
    // obj2 and obj2.var get created
    SomeObject obj2 = new SomeObject();
    // old obj2.var becomes eligible for GC
    obj2.var = obj1.var;
    // obj1 becomes eligible for GC
    obj1 = null;
    

    In the end, two objects remain that do not get GCd - obj2 and the former obj1.var which is now referenced as obj2.var.

    Note: In a special case of ObjectVar class being a non-static inner class of SomeObject, keeping a reference to obj1.var would also keep obj1 around. This is because internally the SomeObject.ObjectVar class has a hidden variable of type SomeObject, which references the outer object of the inner class.

    0 讨论(0)
  • 2021-02-07 09:19

    Yes of course.

    Remember, what you store in the var field is actually reference to the object, not the object itself. So when GC collects obj1, the var object is untouched (must not be touched), especially since it has a reference from obj2, which is still alive and well..

    0 讨论(0)
  • 2021-02-07 09:27

    Simply put, if an object is still reachable by a path of references, it is guaranteed to survive collection. If there is no such path, the object can no longer be accessed, and may safely be collected.

    After the first two lines, the memory looks like this:

    o1  --> SomeObj#1 --> ObjectVar#1
    o2  --> SomeObj#2 --> ObjectVar#2
    

    All 4 objects can be reached, if a garbage collection were to occur at this time, none of them would be collected.

    After the 3rd line, it looks like this:

    o1  --> SomeObj#1 --> ObjectVar#1
                          ^
    o2  --> SomeObj#2 -----    ObjectVar#2
    

    Now, only 3 objects can be reached; the garbage collector may remove ObjectVar#2.

    After the 4th line, it looks like this:

    o1      SomeObj#1 --> ObjectVar#1
                          ^
    o2  --> SomeObj#2 -----   ObjectVar#2
    

    Only two objects are still reachable; the garbage collector may remove SomeObj#1 and ObjectVar#2, but must keep SomeObj#2 and ObjectVar#1.

    0 讨论(0)
  • 2021-02-07 09:31

    Yes - the behaviour is as you describe. The general rule for garbage collection is that objects only become eligible when you cannot reach them through any hard reference. Any objects you can reach this way will thus never be garbage collected (with the exception of soft / weak references.)

    0 讨论(0)
提交回复
热议问题