When an array of objects is not referenced anymore, does the objects in that array are garbage collected too? (assuming no variables are referencing the elements)
In this page, http://java.sys-con.com/node/37613
it says -
"The biggest danger is placing an object into a collection and forgetting to remove it. The memory used by that object will never be reclaimed."
If you make sure to nullify the references, why will that memory be unclaimed?
Thanks
When an array of objects is not referenced anymore, does the objects
in that array are garbage collected too? (assuming no variables are
referencing the elements)
Yes.
"The biggest danger is placing an object into a collection and
forgetting to remove it. The memory used by that object will never be
reclaimed."
This is when you are holding a reference to the collection. For example, if you have a Map in which you put a key-value and then forget to remove then it stays there for ever. Think http sessions, if you use something in ServerContext or some such at start of request using session id as key but fail to remove it at end of the request processing..
For the first question, the answer is yes, absolutely: the objects inside non-referenced array and no other references do get garbage collected.
As for the second question, the document talks about placing forgetting an object inside a referenced collection, for example a cache of some sort, a static field, a thread-local store, etc.
It won't be unclaimed if nothing references it. The article says that if you nullify a reference, but the object is still in a referenced collection (hence referenced), it won't be collected.
Generally speaking, anything that's not referenced is garbage collected. So, yes, those objects would be garbage collected.
Also, note that:
An array is not a collection.
I think that what the person that wrote that meant was make sure you
remember all of the places you're referencing an object, so that if
you intend to remove it, it gets removed (and there are no lingering
references to it).
Related
the code is very simple:
myKpi = "a";
Data.add(myKpi);
and then I want to remove myKpi from memory because it has been saved in the list Data.
I have read that I can do sth like myKpi=null, but I donĀ“t know if it will afect the value of Data.
First, myKpi is just a reference to the instance. That means you can't "remove" myKpi from memory (at least not the instance it references).
Second, since the instance that is referenced by myKpi is added to Data you can't remove that instance since both references refer to the same instance.
Third, you can't manually remove an instance from the heap. All you can do is remove all references and then "ask" the JVM to do garbage collection (via System.gc()) which it will probably do but there's no guarantee it will be done (and what will actually be deleted).
How about
Data.remove(myKpi);
What type of List do you use?
This question already has answers here:
xor operation between java references
(4 answers)
Closed 6 years ago.
As Java doesn't provide a way to get the address of the object, is it feasible to code an XOR linked list?
If yes, can someone please elaborate, how to do that?
I don't believe you can (at least, not using object references for your "next" and "prev" pointers), for the reason you cite: Object addresses are officially opaque. Although we could access the bits of a reference, the JVM can move objects in memory (e.g., when doing memory management), and although I'm not immediately finding a spec citation for it, I believe it's allowed to handle that by modifying the object reference values (literally going and updating every field and such where the old reference is, giving it the new reference). So if we converted the object reference to a long (for instance) and then XOR'd that with another object reference converted to a long, if either object moved (as they can do), once either of those is XOR'd back and converted back into an object reference, it may well no longer be valid.
Consequently, I think you'd need to use something other than object references for the pointers, such as indexes into a big array of object references, at which point I'm fairly sure you've lost the memory benefit of the XOR linked list.
You can never do this in Java.
Even if you use sun.misc.Unsafe to get access to the real addresses of the objects, and even if you use a garbage collector that won't move objects around (Concurrent Mark Sweep doesn't move objects, I believe, as it's "non-compacting"), you have a bigger problem: By mangling the prev and next object references together in an integer, the garbage collector won't realize that they are object references. So it will think the referred objects are unreferenced, and consequently, will collect all your list nodes as garbage.
If you need to save memory, use an array-based list instead of a linked list.
What I am asking might be a stupid question so please pardon me for that.
So it goes like this :
List<Boss> bossList = new ArrayList<Boss>();
Boss b = null;
for(Employee e : List<Employee> myList){
b = new Boss();
b.setEmployee(e);
bossList.add(b);
b = null;
}
So in above scenario, I am creating lot of Boss objects and then de-referencing them(I know I don't need to write "b = null", but i did it for clarity of my question). In normal scenario, I would have marked them to garbage collection, by doeing this, but because in this scenario, I am adding those Boss objects in List collection, are they marked for GC or not? If not then why? And how does List collection work internally to hold references for each Object added, so as to avoid garbage collection?
[EDIT]
The scope of question is only limited to the individual Boss objects created in for loop, considering that this method returns the reference of the List to the outside world.
The Boss objects will not be collected by the GarbageCollector because they are still referenced in the code block that you are posted. bossList is an ArrayList which has an internal array of Object thus holding references to those objects which are added to it.
I such a situation not only the references by you are considered but all referneces in all objects involved.
EDIT: Since you are returning the List in your code the objects will not be marked for garbage collection until the list is no longer referenced in your program.
ArrayList has Object[] elementData internally. When you added b to bossList ArrayList assigned elementData[0] = b. So when you assigned null to b the instance of Boss is still referenced from elementData[0] and cannot be GCed. But since ArrayList instance is referenced only from method's variable after the method returns both ArrayList and Boss instances will be eligible for GC.
Here's what really happens with your code :
Since java is pass by reference, whenever you add b to bossList, bossList starts referencing the memory location which b is pointing to. So when b nullified only link from b to the reference is broken. Thus keeping the object accessible through bossList.
I have written a program for sorting an integer type array which involves the creation another array of the same size. After sorting, there is no use of the new array, so I want to completely get rid of it. So far, I've only found questions relating to the deletion of specific types of elements. Some help?
Information (if needed):
Original Array: A[n]
New Array: B[n]
B[n] has to be completely deleted.
The temp array will be "deleted" (or more correctly, the occupied memory will be eligible for garbage collection) automatically whenever you leave the method performing the sorting (assuming of course that the temp array is created inside the method).
There is almost never any need for explicit memory deallocation in Java.
Array is a reference type in Java. You can make an array reference null if you no longer wish to use it:
arr = null;
Set B to null.
B = null;
This way the garbage collector will clean it up whenever it runs. While you can't control when garbage collection happens since each JVM might have it's own garbage collection algorithm, you may suggest to the system that it should run the garbage collector to free up some memory.
You can do this by using
System.gc();
Note: As mentioned above, System.gc(); will only suggest that garbage collection be carried out but does not assure it.
Normally the gc() frees the memory which has no references. But you can also free the memory with array = null.
If the array is locally defined in your sorting method then it will be scheduled for garbage collection when your method ends as there will be no existing reference to it.
If it is a class or instance variable then set all references to it to null.
In Java you dont have to worry about memory deallocation. There is no such stuff like C's stdlib free(void*) or C++'s delete[] operator. Thee is only the garbage collector.
set B to an empty array
B = [];
Below is the code
ArrayList arList = someMethod();// returning ArrayList with customDO objects
Now somewhere in different class I am getting data from this arList
CustomDo custDO= (CustomDO)arList.get(0);
Will the arList be alive as long as custDO is alive ? If yes, will below piece of code help
CustomDO custDO = ((CustomDO)arList.get(0)).cloneMe();
// where cloneMe has defintion as return ((CustomDO)super.clone());
// CustomDo implements Cloneable
Is there a better way to keep a copy of only the first element of arList and discard the list so that it can be collected by garbage collector ?
Is there a better to keep a copy of only the first element of arList and discard the list so that it can be collected by garbage collector ?
You don't have to make a copy of the list element. As long as you have another reference to it, it will not be garbage-collected, even if the list you got it from is. And the list will be garbage-collected as soon as you remove all references to it.
There is no need in Java to clone anything just to make sure that the object does not disappear. In Java a reference to an object is always valid. It cannot happen that the data for a live reference gets invalid.
You only want to make a copy (clone) if you are afraid that other people who reference the same object might change its contents (calling some setter on it) in ways that would cause trouble for you (or you want to have a private copy to change it without affecting others).
// reference to first object
CustomDO custDO = ((CustomDO)arList.get(0));
// let arList be garbage collected
arList = null;
Another thing you should know is that Collections clone() methods do a shallow (flat) copy. Sometimes you need to have deep copies (to allow modifing them independedly)
As long as you have access to CustomDO custDO object, it will not be garbage collected. The list can be garbage collected if there is no reference to it.
The ArrayList is an ordinary Object, and only references to this object will keep the list alive. Of course, as long as the list is alive, all its elements are also alive, but the converse does not hold.