0

This is the data provider:

class Item {
  private String text;
  public Item(String txt) {
    this.text = txt;
  }
  public String get() {
    return this.text;
  }
  public static Item next() {
    return new Item("hello");
  }
}

Now I'm trying to do this (just an example, to understand how it works):

List<String> texts = new LinkedList<>();
for (int i = 0; i < 10000; ++i) {
  Item item = Item.next();
  texts.add(item.get());
}
// do we still have ten thousand Items in memory,
// or they should already be garbage collected?

I wonder whether GC will destroy all Item objects, or they will stay in memory since my List holds 10000 links to their parts (text)?

yegor256
  • 102,010
  • 123
  • 446
  • 597
  • It will only clean up objects which are not strongly unreachable. What is the problem you are facing? – Peter Lawrey Sep 08 '13 at 14:09
  • My actual problem is Memory leak when working with MongoDB (http://stackoverflow.com/questions/18684598/memory-leak-in-mongodb-cursor-outofmemory), but here I'm trying to confirm that it's not my code that is leaking – yegor256 Sep 08 '13 at 14:18
  • The only difference between your code and the simple case of adding the strings directly to the list is that you needlessly slaughter 10,000 cute little objects. – Hot Licks Sep 08 '13 at 14:19
  • Of course, short of a bug in the JDK (or in JNI code), a "memory leak" is impossible in Java. But it's fairly common to "forget" objects -- eg, create a long list, replace it, but forget that it's also referenced from somewhere else (perhaps from an object in the new list). There are some tools that can help diagnose this. – Hot Licks Sep 08 '13 at 14:23
  • If you want to find the memory leak you should use a memory profiler or analyse a heap dump. The JDK comes with a free one as does many IDes. Its much better than guessing. – Peter Lawrey Sep 08 '13 at 15:32

1 Answers1

8

Because you're not keeping references to the Item objects, just to the strings, the Item objects are eligible for GC. The strings are not, as they are referenced.

After the first iteration of your loop, you have this:

+------+
| item |
+------+
| text |----+
+------+    |   +---------+
            +-> | "Hello" |
            |   +---------+
+-------+   |
| texts |   |
+-------+   |
| 0     |---+
+-------+

So both item and texts point to the string, but nothing points back to item, so that Item can be GC'd.


Slightly off-topic:

Your example as shown will have only one String instance which is referenced 10,000 times in the list, because it's a string literal, and string literals are intern'd automatically. But the answer wouldn't change if it were a different string in each case. The strings are separate from the Items.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875