0

Consider the following scenario:

String dude = "Harold";

//some stuff

dude = "Kumar";

Once dude is assigned its second value of "Kumar", a whole new object separate from "Harold" comes into existance. What I am wondering is, since there is clearly no use for "Harold" any more, is it garbage collected instantly or at some later time when the JVM deems it appropriate?

UPDATE:

Just because dude has been set to a new value (object) does not necessarily mean all reference to the old object have been eliminated. If another reference invokes dude after "Harold" and before "Kumar", it will obviously retain the "Harold" object:

String dude = "Harold";

//some stuff

String interim = dude;

dude = "Kumar";

System.out.println("dude = " + dude);
System.out.println("interim = " + interim);

prints

dude = Kumar
interim = Harold

So there are more considerations than I originally envisioned therefore the initial value doesn't necessarily have to be out of scope after the change.

amphibient
  • 29,770
  • 54
  • 146
  • 240
  • when JVM deems appropriate. Or rather, when GC gets called, it will collect what it deems collectable. If you want to force garbage collection, you need to run `System.gc()` a few times in a row. Like `for(int i = 0; i<5; ) System.gc(); ` Then again, if you have assigned them just like that, both will remain as they're both literals which will reside on the data heap. – Shark Feb 12 '13 at 16:06
  • @Alexey - interning no longer works that way starting with java 7 – radai Feb 12 '13 at 16:07
  • @amphibient. I don't believe that your updated example correctly explains the situation. Strings are immutable. When String interm = dude, interim creates a new address to store the value "Harold". Hence you would essentially have two different addresses that store the value "Harold", one referenced by interim and the other referenced to dude. – Wee Kiat Nov 25 '15 at 02:50

7 Answers7

5

Nothing is garbage-collected instantly, and trying to force garbage collection is discouraged (and becomes increasibgly difficult with each java release).
Yes, the minute "Harold" is no longer reachable (no chain of pointers leads to it) it becomes eligible for garbage collection and may be collected (if the GC ever runs). having said that, Strings may be allocated in the const pool, which resides in the perm gen and is not GC'ed* (at least up until java 7). more info on interning strings here: http://www.codeinstructions.com/2009/01/busting-javalangstringintern-myths.html

* - not entirely accurate, the const pool is GC'ed even though its in perm gen. its complicated.

radai
  • 23,949
  • 10
  • 71
  • 115
2

Normally garbage collection doesn't happen immediately. Furthermore, Strings are immutable and are kept in a global table (by most JVMs as far as I know) so it might never be collected.

Andres Olarte
  • 4,380
  • 3
  • 24
  • 45
2

This one: "at some later time when the JVM deems it appropriate". Garbage Collection costs CPU and can mean pausing threads. GCs are hideously complicated things that constantly balance CPU vs memory usage.

As others have said, Strings are more complicated, but I assume you just wanted to know in general, for java objects. I don't think all this waffle about String is really relevant to your question and is making this Question far more complicated than it needs to be!

David Lavender
  • 8,021
  • 3
  • 35
  • 55
2

While pretty much every current implementation of the Java spec uses a tracing garbage collector, I don't believe the specification requires that the heap be managed using a tracing GC.

One can imagine GC implementation incorporates reference counting. In this variation to the case above (engineered to avoid the const pool detail):

String dude = new String("Harold");
//
dude = new String("Kumar");

The original object referenced by dude's ref count goes to zero, and could be garbage collected immediately.

The net point being -- with Java, there is no guarantee, but usually you don't have to worry about it.

Also, an old reference that talks about Java GC.

Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52
2

since there is clearly no use for "Harold" any more

How have you come to this conclusion? Just by looking at the single class where you have made the reference? But according to the Java Language Specification, string literals are reused in the following cases

  • Literal strings within the same class in the same package represent references to the same String object.
  • Literal strings within different classes in the same package represent references to the same String object.
  • Literal strings within different classes in different packages likewise represent references to the same String object.
  • Strings computed by constant expressions are computed at compile time and then treated as if they were literals.
  • Strings computed by concatenation at run-time are newly created and therefore distinct.
  • The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.

So unless you are sure that all none of the above are true, you probably can't expect it to be even eligible for garbage collection.

Shiva Kumar
  • 3,111
  • 1
  • 26
  • 34
  • under which practical use case scenario can "Harold" still be used after `dude` has been set to "Kumar"? the only one I can think of is if there is another reference to `dude` that is invoked after "Harold" and before "KUmar" including but not limited to `public string getDude() { return this.dude; }` for example. – amphibient Feb 12 '13 at 17:27
1

Lets forget, that constant String may be handled differently. The main reason why the object is not immediately garbage collected is that there may be other references to it. For example if your "some stuff" contains a statement like

t = dude;

The object is not unreachable when you assign a new value to dude. To find out all references is rather costly and therefore only done when necessary.

Henry
  • 42,982
  • 7
  • 68
  • 84
0

String is immutable. When you reassign variable dude dude = "Kumar" older string object get out of scope.

And when Garbage Collector start working, it collected that object.

Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103