简体   繁体   中英

Can objects make each other 'undeletable' by referencing each other?

So lets say there are two classes:

public class A {
    B reference = new B(this) //B isn't garbage collected because A references it
}

public class B {
    A reference // A isn't garbage collected because B references it
    public B(A ref) {
      reference = ref;
    }
}

And then a third class creates a new A object. Then, when it wants to get ride of it, it sets that pointer to null . Wouldn't there be some weird persistant loop caused by A and B because they both reference each other? Neither can be collected because they keep each other "alive". Or is the JVM too smart for that and realizes that the rest of the program doesn't know about them?

It feels like this might cause some sort of memory leak.

If this is possible, how do you fix it? Bidirectional references are very common in code. There are many cases when object 1 knows about object 2 and object 2 knows about object 1. How do you make sure that they are deleted.

NOTE: I wrote all this in my web browser, so forgive any errors

No. The garbage collector doesn't count references to know is an object is collectable or not. An object is collectable if it's not reachable any more through a chain of strong references from any root (static variable, or running thread).

If only references to A and B are A and B themselves , then they are eligible for garbage collection.

Java's GC considers objects eligible for garbage collection if they aren't reachable through a chain starting at a garbage collection root. Even though objects may point to each other to form a cycle, they're still garbage if they're cut off from the root.

Garbage collection starts from roots of active objects, so you need to concentrate on these sets. If you have a long chain of objects that are referenced from an active object (something pointed to by stuff currently being used) then you can create memory leaks, but if you turn a reference to null, the objects will still be garbage collected.

In other words, if you have A->B and B->A but nothing pointing to both, they'll still be collected: because they can't be reached from the root set of live objects.

The root set comes from the set of all threads in the program:

http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx

and

What are the roots?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM