Geek
Geek

Reputation: 27219

Basics about Java memory leak

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

Answers (9)

slim
slim

Reputation: 41271

Try a picture:

enter image description here

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

gkuzmin
gkuzmin

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

amicngh
amicngh

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

Sanjay T. Sharma
Sanjay T. Sharma

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

Max
Max

Reputation: 3593

Java passes by value indeed. However you are passing a reference by value, not an instance of an object.

Upvotes: 1

Chris
Chris

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

Dahaka
Dahaka

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

Dave Rager
Dave Rager

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

assylias
assylias

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

Related Questions