Reputation: 27219
I read that Java is passed by value . So lets say we have this code and say that the HashMap somehashMap
has a longer life time than foo
. So foo is not allowed to be garbage collected even though it has done its work simply because we put foo inside the Map and then forgot to remove from it . Now going by the logic of the answer in the post that I linked to we are actually passing a copy of the reference of foo
to the method put()
right ?In that case putting the foo
into the HashMap
shouldn't prevent it from getting garbage collected . Can you please help me understand what is going on here ? What am I missing exactly ?
public void someMethod(){
Foo foo = new Foo();
somehashMap.put(fooKey,foo);
}
Upvotes: 3
Views: 6436
Reputation: 41271
Try a picture:
Boxes are objects. Unboxed letters are variables.
At the start you just have your hashmap, which I'm assuming exists before your function is called, and continues existing afterwards.
Then new Foo()
creates a new object, and f=
creates a variable which refers to it.
Then hashmap.put(k,f)
creates an entry in the hashmap, which points to the same object as f does.
Then when you exit the function, the local variable f
ceases to exist, but everything else remains.
The Garbage Collector won't remove the Foo object, because the hashmap still points to it. And that's what you want -- if you later call hashmap.get(k)
, you would expect to get that Foo object.
If you remove the entry from the hashmap - hashmap.remove(k)
then the Foo object can be garbage-collected.
If the hashmap itself stops existing, then the Foo object can be garbage-collected.
Upvotes: 6
Reputation: 2474
Most languages with garbage collector support some kinds of weak references. You can find a weak hash map implementation in Java, for example. If you put a foo object into the weak hash map and garbage collector will run then the foo object will be collected and removed from the weak hash map if no other pointers to foo exists (except week pointers). Sometimes you can escape memory leaks this way.
Upvotes: 3
Reputation: 7899
we are actually passing a copy of the reference of foo to the method put() right?
Yes, Java is passing a copy of the reference which intern map hold reference
to thesame object
in memory (heap
) so it will not be eligible for GC until your map.
Upvotes: 2
Reputation: 23248
Garbage collection isn't applicable to references but to actual objects which reside in heap. When you put foo
in the Map
, you are basically helping it "escape" out of its current scope and putting it in the same scope/life-time as somehashMap
.
References in Java are handled transparently behind the scenes. When you put the foo
reference in the map, a copy of the reference is actually passed to the put
method call but the underlying object i.e. new Foo()
is the same for both the original and the copied references. Let's look at the below snippet:
public void doIt() {
Object f1 = new Object();
Object f2 = f1;
Object f3 = f2;
}
In the above snippet, how many objects are garbage collected after execution of doIt
completes? It's just the single new Object()
which we created. Rest all are simply references or aliases which are used to point to the same object.
Upvotes: 11
Reputation: 3593
Java passes by value indeed. However you are passing a reference by value, not an instance of an object.
Upvotes: 1
Reputation: 4681
I don't think you're clear on what a reference actually is.
You're partially right that 'foo' is a reference to an object, and adding it to the hashmap effectively creates a second reference to the same object.
However, that's exactly why the object isn't going to get garbage-collected when your 'foo' variable disappears. Objects are garbage-collected only when there are no references left - you start out with one reference (foo), then create a second (inside the hashmap), the first reference vanishes when your function ends, but you still have one reference left.
Upvotes: 6
Reputation: 517
As long as foo is in the HashMap it can not be garbage collected, because Java does not know you will never use it again. foo can be garbage collected as soon as all references are end-of-life.
Upvotes: 2
Reputation: 8160
The pass by value in the case of this put
method is the value of the reference to foo
. Since foo
is reference counted, as long as somehashMap
holds the reference, foo
won't get garbage collected.
I did find a memory leak like this in some code that I inherited where someone was using the map to cache images but when the image was needed again, instead of grabbing the cached image, a new one was created anyway and pushed into the map with a new key.
Upvotes: 1
Reputation: 328835
An object can't be garbage collected as long as it is reachable. In your case, foo can be reached by Foo foo = someHashMap.get(fooKey);
so can't be garbage collected as long as it is in the map and the map itself is reachable.
Upvotes: 7