可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Suppose I have a doubly linked list. I create it as such:
MyList list = new MyList();
Then I add some nodes, use it and afterwards decide to throw away the old list like this:
list = new MyList();
Since I just created a new list, the nodes inside the old memory area are still pointing to each other. Does that mean the region with the old nodes won't get garbage collected? Do I need to make each node point to null so they're GC'd?
回答1:
No, you don't. The Java GC handles cyclic references just fine.
Conceptually, each time the GC runs, it looks at all the "live" root references in the system:
- Local variables in every stack frame
- "this" references in every instance method stack frame
- Effectively, all static variables (In fact these are really referenced by
Class
objects, which are in turn referenced by ClassLoader
s, but lets ignore that for the moment.)
With those "known live" objects, it examines the fields within them, adding to the list. It recurses down into those referenced objects, and so on, until it's found every live object in the system. It then garbage collects everything that it hasn't deemed to be live.
Your cyclically referenced nodes refer to each other, but no live object refers to them, so they're eligible for garbage collection.
Note that this is a grossly simplified summary of how a garbage collector conceptually works. In reality they're hugely complicated, with generations, compaction, concurrency issues and the like.
回答2:
If you created your own double linked list, and you put in this double linked list Containers (that contain items from your list); only those containers are linked one to another.
So in your list you'll have an object A contained in A'. A' is linked to B' and B' is a container that hold B etc. And none of the object have to reference another.
In a normal case those containers won't be available from outside (only the content is interesting); so only your list will have references to your containers (remember that your content isn't aware of his container).
If you remove your last reference to your list (the list, not the container nor the content) the GC will try to collect your list content, witch is your containers and your contents.
Since your containers are not available outside the only reference they have is one each other and the main list. All of that is called an island of isolation. Concerning the content, if they still have references in your application, they will survive the GC, if not they won't.
So when you remove your list only A' and B' will be deleted because even if they still have references, those references are part of an island. If A and B have no more references they will be deleted too.
回答3:
No -- Java (at least as normally implemented) doesn't use reference counting, it uses a real garbage collector. That means (in essence) when it runs out of memory, it looks at the pointers on the stack, in registers, and other places that are always accessible, and "chases" them to find everything that's accessible from them.
Pointers within other data structures like your doubly-linked list simply don't matter unless there's some outside pointer (that is accessible) that leads to them.
回答4:
No, the GC will reclaim them anyways so you don't need to point them to null. Here's a good one paragraph description from this JavaWorld article:
Any garbage collection algorithm must
do two basic things. First, it must
detect garbage objects. Second, it
must reclaim the heap space used by
the garbage objects and make it
available to the program. Garbage
detection is ordinarily accomplished
by defining a set of roots and
determining reachability from the
roots. An object is reachable if there
is some path of references from the
roots by which the executing program
can access the object. The roots are
always accessible to the program. Any
objects that are reachable from the
roots are considered live. Objects
that are not reachable are considered
garbage, because they can no longer
affect the future course of program
execution.
回答5:
The garbage collector looks if objects are referenced by live threads. If objects are not reachable by any live threads, they are eligible for garbage collection.
It doesn't matter if the objects are referencing each other.
回答6:
As others have pointed out, the Java garbage collector doesn't simply look at reference counting; instead it essentially looks at a graph where the nodes are the objects that currently exist and links are a reference from one object to another. It starts from a node that is known to be live (the main method, for instance) and then garbage collects anything that can't be reached.
The Wikipedia article on garbage collection discusses a variety of ways that this can be done, although I don't know exactly which method is used by any of the JVM implementations.
回答7:
The garbage collector looks for objects that isn't referenced anywhere.
So if you create a object and you loose the reference like the example the garbage collector will collect this.