I serialized an object of user defined linked list class, as every node of that list get a memory location in heap, while deserializing if the memory location is already occupied for a particular node , for example
if the memory of node 2 i.e. 200 is already occupied then how the node 1 knows about it and how the list deserialize?
Or in java the memory allocation happens in some different way.
JVM is responsible of object's management in memory. After any GC is executed, objects allocated in memory can be moved, so the LinkedList doesn't actually points a fixed adress but reference
Java has no pointers, only references to objects (safe references). A reference is similar to a pointer, because it points to a variable, an object, but you cannot view or edit the address memory of this reference (unlike C for example).
Generally speaking you would not have to do any thing about about heap manually in Java.
Serialization should not effect heap unless you have some references to serialized node.
Interms to linked list two nodes don't need to know where other node is in memory.
Hope this answers you question.
Related
i am trying to understand how both list are represented in heap and stack. As far as i know objects are stored in Heap and references are stored in the stack.
Since the lists are objects it makes sense for them to be stored in the heap, but how are their elements represented(One is of fixed size and the other not)? Does every single element in the collection has a reference in stack or there is one reference pointing only to the collection itself?
Also the LinkedList elements contain more data, i suppose that means more memory will be allocated when storing them, am i right?
I apologize if this question has been asked before, it's just i wasn't able to find an answer to satisfy my questions!
Example in c++
Employee emp=new Employee();
Now here x bytes are created to store Employee. And y bytes are required to store reference. Hence x+y bytes are required.
Now in c++ since there is no garbage collection, its programmers duty to destroy the object.
Employee emp2=emp;
Question1: Now does it create one more address space of (x+y) for emp2 ?
In Java
It just points to the object in heap.
Question2 : So does this mean if the same object is added into a ArrayList in java, lets say 100 times then the memory used is only to store the reference of the object in heap? i.e only 100*y+x amount of memory will be used?
So does this mean if the same object is added into a ArrayList in java, lets say 100 times then the memory used is only to store the reference of the object in heap? i.e only 100*y+x amount of memory will be used? - Yes. In collections only references to actual objects (which are almost always on heap) are added.
As a side note, java has 4-byte references irrespective of the architecture (32 bit / 64 bit).
There is the stack memory of function calls' local variables; a stack as function calls are nested.
This is the memory for variables. In Java a reference to an object. The object itself is stored on the heap, garbage collected. Also an array is an Object in Java. Java does not have C structs on the stack. This is a historical design decision to keep everything simple, as successor of "complex" C++.
Now in C++ you have an immediate struct or array on the stack (without new/malloc). You then need a copy constructor, that shovels the data from one space to the other (stack or heap).
The effective difference is that in C one can have a linked list where every node is fat, with the data inside.
In Java, say a LinkedList<T> every node (a heap object) will contain an additional indirection, a reference to a T data object.
The data may be shared in Java, and are possibly copied in C.
From this perspective you can do your own calculations of memory usage. I feel the need to mention that Java's good garbage collection in general is better than malloc/free of C. So Java certainly is not that bad.
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.
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.
Programing languages like C,C++ will not store array values in Heap rather it keeps the value in STACK. But in Java why there is a necessity to keep array values in heap?
In Java, arrays (just like all other objects) are passed around by reference: When you pass an array to a method, it will get a reference pointing to the same location in memory, no copy is being made. This means that the array needs to remain "alive" after the method that created it, and so cannot be stored in the stack frame for the method. It needs to managed by the garbage collector, just like all other objects.
There is some research going in to optimize JVM memory allocation using "escape analysis": If an object (such as an array) can be guaranteed to never leave the current scope, it becomes possible to in fact allocate it on the stack, which is more efficient.
A short answer is that an array in Java is a reference type, and reference types live on the heap. It's worth noting that in C#, one can switch to unsafe mode and initialise arrays with stackalloc which will create the array on the stack. It's therefore quite probable that the VM would allow you to make an array on the stack, and it's merely an implementation detail that means arrays all live on the heap.
int[]a={10,20,30};
this array stores on stack, but the following array stores in heap:
`int[]num=new int num[2];`//here we build the object of array , object always located in heap
always treat arrays like java object, so do not be confused by the fact that arrays don't store on ram when we have a declaration like the one above.