All,
If I were to write a function to delete a node (given headNode and data as input parameters) from a linkedList in Java. I would find the node that has "node.data=data", and delete it by pointing its previous node to its next node *^. My question is, do we have to point the "to be deleted" node to null? to free the memory? or the GC will take care of objects no more accessed in heap.
*^: say A->B->C->D , if B.data=data, then make A->C . is B->Null necessary?
please let me know if its not clear, I will edit it. Thanks.
If you want to delete Node B you just need for A to point to C. The garbage collector will take care of your B nodes as there won't be any references left to it.
The following explanation is quoted from http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.html
An Object becomes eligible for Garbage collection or GC if its not reachable from any live threads or any static refrences in other words you can say that an object becomes eligible for garbage collection if its all references are null. Cyclic dependencies are not counted as reference so if Object A has reference of object B and object B has reference of Object A and they don't have any other live reference then both Objects A and B will be eligible for Garbage collection.
Generally an object becomes eligible for garbage collection in Java on following cases:
1) All references of that object explicitly set to null e.g. object = null
2) Object is created inside a block and reference goes out scope once control exit that block.
3) Parent object set to null, if an object holds reference of another object and when you set container object's reference null, child or contained object automatically becomes eligible for garbage collection.
4) If an object has only live references via WeakHashMap it will be eligible for garbage collection.
As everyone has said you don't need to set it to null. I just want to add that I had a similar question before which might not be obvious. If you have a doubly linked list, where each node references the previous and the next node, for example A-B-C-D and you remove C-D so that you're left with A-B. You also do not need to worry about C or D even though both of them still have a reference to them (from the other one). Apparently the GC is smart enough to take care of that case as well
No you don't have to set B to null. The Java garbage collector will free the memory for any object not reachable anymore.
Related
I've noticed that a lot of code online for the remove node or delete node function of a singly LinkedList merely set the previous node's next to the next of the node to be removed. But isn't that an incomplete deletion, because the deleted node is still pointing to it's next?
For example
A->B->C
If you delete B, you should make A point to C. But if you don't make B point to null, doesn't B still exist because it's pointing to C?
Like wise, for a doubly linkedList in java, if you were deleting a node wouldn't you need to make sure that the node is no longer pointing to anything for it to be truly deleted?
if you don't make B point to null, doesn't B still exist because it's pointing to C?
No. The reason is that as there is not any reference towards B, it will be garbaged collected. It doesn't matter if it (B) is still pointing to something.
Like wise, for a doubly linkedList in java, if you were deleting a
node wouldn't you need to make sure that the node is no longer
pointing to anything for it to be truly deleted?
The principle is the same. What changes is that you need to change two references: the previous node of the node being deleted (making it point to the next of the node being deleted) and the next of the node being deleted (making it point to the previous of the node being deleted).
When there are no references to the node being deleted, this will be garbaged collected.
In general, when there isn't a reference pointing to some object, this will be garbaged collected at some point.
Here is a very similar post that may be useful to you: Garbage collector in java - set an object null
I presume you are talking about Javas LinkedList<>. It's probably because the garbage collector will get it.
No.It will be garbage collected.Unreachable objects which are no longer referenced by any part of the program will be cleared by garbage collector in java.Garbage collector frees up the heap memory by destroying the unreachable objects.
Just wondering if that when you set
obj1 = null;
the object is eligible for gc, is it also true that everything with a null value is technically eligible also?
I'm particularly wondering about arrays, say if you have something like
[obj1, obj2, null, obj3, null, obj 4, obj5]
Can the gc run and remove the null object so the elements are empty?
Garbage collection collects objects, it does not collect references to objects. The idea of garbage collecting a null therefor makes no sense. What GC does at the simplest level is notice when an object no longer has any references pointing to it, and at that time it will free up the memory. It doesn't care how many references point to null, it only cares how many incoming references an object has.
SO no, GC will never remove nulls from an array. That's not what it does. Besides which, a null value in an array is perfectly valid and removing it would break many programs.
There is no "null object", and null is the closest thing that exists to an empty reference. The key definitions are in the Java Language Specification, 4.3.1. Objects:
An object is a class instance or an array.
The reference values (often just references) are pointers to these
objects, and a special null reference, which refers to no object.
obj1 = null; changes the reference variable obj1 to be null. If it previously referred to an object it no longer does so.
There may be other references that refer to that object, so that the object remains reachable, and the garbage collector will leave it alone. If obj1 was the last reference to the object, it is no longer reachable, and is eligible for finalization.
I understand that when an object is added to a List, the List retains a reference to that object based on answer from this question
Is this java Object eligible for garbage collection in List
How then how do you make the object in the List eligible for garbage collection so that it's removed from the heap and not taking up memory?
I ask because in JavaFX, a Vboxs getChildren method returns observable list containing the children nodes of the vbox. If a UI element is removed but not eligible for garbage collection, will this object still be on the heap consuming memory?
Removing the references from that should make them subject of garbage collection (as long as no other object keeps references!).
You know, that is the whole idea how a GC works: it keeps those objects that are alive (can be reached from your initial starting point). Everything else is garbage; and subject to disposal once the GC decides to collect that garbage. And just to be precise here: you have to understand that these are two different activities. There might be a long time between object X "turns into garbage"; and "X gets collected; and memory is freed up".
One can use WeakReferences to avoid this; but of course, that requires that some piece of code would be pushing such WeakReference objects into the list initially. So, if you "own" this code, you could change that. But of course: that means that you always have to check if the object behind the WeakReference is still there when accessing the WeakReference.
How then how do you make the object in the List eligible for garbage
collection so that it's removed from the heap and not taking up
memory?
Assuming that those objects are only referenced by this List, simply use the clear method
If a UI element is removed but not eligible for garbage collection,
will this object still be on the heap consuming memory?
As long as an object is been hard referenced by at least one another object that is not itself eligible for garbage collection, the objet will be itself not eligible for garbage collection so it won't be collected by the GC it will then remain in the heap.
If you cannot remove the object from the List, the only way I can think about to handle this would be wrapping your Objects into a WeakReference.
So I learned that in a singly linked list if you remove a node in the middle, the rest of the list will be garbage collected as well since there will be a ripple effect as each node behind it gets dereferenced.
My question is what about a tree where each node has references to it's children as well as a reference to a parent. If I remove a node in the middle(non-leaf node) would that cause a memory leak since it would reference it's children and they would reference it? So if I wanted to remove a subtree, I would have to remove all the nodes in it from the bottom up?
You should read about the concept of reachability. It is defined in the javadocs, in the description of the package java.lang.ref.
Once an object is not strongly reachable by any thread, it is eligible for garbage collection.
The objects that are strongly reachable by a thread T are:
objects referenced by local variables in the call stack of T,
objects referenced by static fields of any classes, and
objects (strongly) referenced by strongly reachable objects.
If you remove a node from the tree you describe (simply by removing the reference on a parent node to a child), and there are no remaining references to the portion of the tree under the node you removed, then those objects are not strongly reachable. Even if they form some kind of cycle, the JVM is smart enough to determine that those objects are not strongly reachable (that is, they reference each other, but none of them can be reached by any code). Therefore, they are eligible for garbage collection.
You could remove the start node and remove the reference to that node in its parent.
To remove a subtree you just have to remove the reference to it in its parent. So long as no other references are held to it or its children, it will be garbage collected.
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?
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 ClassLoaders, 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.
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.
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.
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.
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.
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.
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.