Reputation: 1267
If I add objects to HashMap
and then just call remove
method when they are no longer needed, does it guarantee the resources they take will be released (given there are no other references to them)?
Upvotes: 3
Views: 7960
Reputation: 1
I place objects in a HashMap and then remove them.
The class of the objects placed in the HashMap:
public class ObjectTestsub {
String name;
public ObjectTestsub(String name) {
this.name = name;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("ObjectTestsub: " + name + " is garbage collected");
}
}
The main:
public class ObjectTest {
HashMap<String, ObjectTestsub> map;
public static void main(String[] args) {
var map = new HashMap<String, ObjectTestsub>();
for (int i = 0; i < 1000000; i++) {
map.put("Obj" + i, new ObjectTestsub("first " + i));
map.remove("Obj" + i);
}
}
}
The output:
....
ObjectTestsub: first 822685 is garbage collected
ObjectTestsub: first 822684 is garbage collected
ObjectTestsub: first 822683 is garbage collected
ObjectTestsub: first 822682 is garbage collected
....
ObjectTestsub: first 822677 is garbage collected
ObjectTestsub: first 822676 is garbage collected
ObjectTestsub: first 822675 is garbage collected
ObjectTestsub: first 822674 is garbage collected
The quantity of the objects "destroyed" is matter of the Java garbage collector. What is relevant here is that some objects are collected (so have been released). Everything goes fine.
Now I change the code:
public class ObjectTest {
HashMap<String, ObjectTestsub> map;
public static void main(String[] args) {
var map = new HashMap<String, ObjectTestsub>();
for (int i = 0; i < 1000000; i++) {
map.put("Obj" + i, new ObjectTestsub("first " + i));
}
System.out.println("first part has DONE! size: " + map.size());
for (int i = 0; i < 1000000; i++) {
map.remove("Obj" + i);
}
System.out.println("second part has DONE! size: " + map.size());
}
}
Here the output:
first part has DONE! size: 1000000
second part has DONE! size: 0
There is no message from the "destructor" of the "ObjectTestsub" objects anymore. It looks like they haven't been released...
Where is the trick? :/
Upvotes: -1
Reputation: 2101
No, as you may have a reference to that object from somewhere else.
Simple example:
Map < int, Object > map = new HashMap < int, Object > ();
CustomObject x = new CustomObject();
map.put(1, x);
map.remove(1);
//you still have access to x
Upvotes: 1
Reputation: 22963
The HashMap
entries are stored in an array. If you remove an entry the related array position will be null
. So the hashMap
has not anymore a reference to the removed value
object.
Then the normal rules for the garbage collection will be applied for the value
object.
Simple code to verify.
public class REPL7 {
public static void main(String[] args) throws Exception {
Map<String, Foo> map = new HashMap();
map.put("one", new Foo("foo one"));
map.put("two", new Foo("foo two"));
// make the backing array accessible
Field field = map.getClass().getDeclaredField("table");
field.setAccessible(true);
Object[] obj = (Object[]) field.get(map);
// two references to Foo objects will be shown
System.out.println("obj = " + Arrays.toString(obj));
map.remove("one");
// only one reference to a Foo object will eb shown
System.out.println("obj = " + Arrays.toString(obj));
}
}
class Foo {
String marker;
Foo(String marker) {
this.marker = marker;
}
@Override
public String toString() {
return "Foo{" + marker + '}';
}
}
Upvotes: 2
Reputation: 379
Garbage collection always done in heap memory where all objects initialize. When you call remove
method in HashMap
it only removes the id and value from it not the object you created.
Upvotes: 1
Reputation: 213
If the Map is the only thing with a reference to the Object and you remove the Object reference from the Map then yes, the Object is no longer referenced from anywhere and will be eligible for GC. As always, the resources it took are guaranteed to be released, but there is no guarantee when that will happen.
Upvotes: 0
Reputation: 26961
If you are sure of:
there are no other references to them
Yes, they're candidates to GC, what does not mean they will be inmediatelly recollected!!.
You can do with:
System.gc();
But is not a good idea. For further info check this and this questions.
Upvotes: 4