1
String samplel = "ToBeGarbageCollected";
String sample2 = samplel.substring(0, 1);
samplel = null;

I know substring internally will keep a reference for original String.

But by explicitly defining samplel as null, will sample1 and sample2 be available for garbage Collection?

I remember seeing somewhere if a parent object is explicitly set to null all child values are available for garbage collection. Will this hold good for the above? I am just curious if this the parent child relationship scenario? If not, will this cause sample1 or sample2 to be available for garbage collection?

String samplel = "ToBeGarbageCollected";
String sample2 = new String(samplel .substring(0, 1));
samplel  = null;
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
Hero
  • 639
  • 4
  • 12
  • 33

2 Answers2

6

First thing to say is that garbage collection doesn't happen immediately. So assigning null to anything does not / cannot cause garbage collection. What is may do is to cause an object to become unreachable ... and that will make it a potential candidate for garbage collection in a future GC run.


Now to your specific examples.

Important Note: the following only applies to older JVMs; i.e. Java 7 update 5 and earlier. In Java 7 update 6, they changed String.substring() so that the target string and resulting substring DO NOT share the backing array. This eliminates the potential storage leak issue with substring.


The substring method doesn't put a reference to the original String in the new String. What it actually does is save a reference to the original String's backing array; i.e the array that holds the characters.

But having said that, assigning null to samplel is not sufficient to make the state of the entire original string unreachable. The original String's entire backing array will be remain reachable ... and that means it won't be a candidate for garbage collection.

But there is another complication. You set sample1 to a String literal, and the String object that represents a String literal is always reachable (unless the entire class gets unloaded!)

But by explicitly defining samplel as null, will sample1 and sample2 be available for garbage Collection?

The original sample1 object will remain fully reachable, and sample2 will remain be reachable unless that variable goes out of scope.

If sample1 had not been a literal and there were no other references to it, then the answer would be different. The sample1 object would be unreachable, but its backing array would still be reachable via sample2.


In your second example, copying the substring causes a new String to be created. And it is guaranteed that the new String won't share the backing array with the original String and the temporary substring. In that case, assigning null is unnecessary.

Will now both sample1 and sample2 be available for garbage Collection?

The answer is the same as for the above for the case where sample1 is a literal.

If sample1 is not a literal and there are no other references to it, then sample1 and the temporary substring would now be unreachable.


I just want to know where does String constructor be helpful.

In theory it will be.

In practice it depends on whether the references are still reachable when the GC eventually gets around to looking ... and also on whether the Strings in question are large enough and numerous enough to have a significant impact on memory usage.

And in practice, that precondition is usually NOT satisfied and creating a fresh String like that usually does NOT help.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • His use of the terminology 'available for garbage collection' is correct: it is clear that the O.P. knows garbage collection doesn't happen immediately, and that this fact does not impact the actual question, right? – Nathaniel Ford Apr 07 '13 at 01:45
  • @NathanielFord - It is not clear to me that he understands what those words mean. I have chosen to answer the question in a way that doesn't assume that understanding. And also so that other people who missed / didn't understand that point can ALSO understand the answer. – Stephen C Apr 07 '13 at 01:55
  • @Suraj - if there are threads accessing or able to access an object, then it is reachable. That is essentially what reachability means. – Stephen C Apr 07 '13 at 02:34
  • @StephenC - Okay but my doubt is why is it said by explicitly setting the parent value as null the child will also be garbage collected. Does this hold good even if child is accessed byt live threads.?? – Hero Apr 07 '13 at 02:37
  • @Suraj - The *"it is said"* is an incorrect characterization of what is happening. Explicitly setting a reference variable to null only changes the reachability status of the child if there are no other reachable variables holding that reference. That includes local variables of live threads ... and anything reachable from them. – Stephen C Jul 24 '13 at 22:39
  • In java 1.7 update 6, substring no longer uses the backing array of the original string. Discussion on Reddit http://www.reddit.com/r/programming/comments/1qw73v/til_oracle_changed_the_internal_string/ – Rodney Nov 26 '13 at 12:53
2

Remember that in Java String is immutable. In this case, sample1 will be discarded, but sample2 never pointed to sample1: it pointed to a separately held immutable string in the JVM that was created at the latest when substring was called.

When you set sample1 to null, the memory it pointed to became available for garbage collection (assuming no other strings held the same value and no other variables were pointed at that location). When you use the new keyword (or implicitly do so through the assignment of a primitive) new memory is allocated on the heap (usually; again, strings are immutable and share the same memory). If no pointers (read: any named variables) point to a given location of memory, it is available for garbage collection.

Remember: in any case where there are no references to an object, it becomes available for garbage collection. Objects are not defined by the variable names assigned to them, but rather are locations in memory, and the variable names act as pointers (references) to those objects. Strings are somewhat different because they are immutable, and the JVM may opt not to garbage collect for reasons independent of references to them.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • So you mean to say . If no threads are accessing sample1 in both the scenarios its available for GC.??? – Hero Apr 07 '13 at 01:44
  • 1
    Yes, but realize that `Strings`, being immutable, are handled differently than a normal object. The JVM may not garbage collect them in the same way since it is often inefficient for it to do so. – Nathaniel Ford Apr 07 '13 at 01:46
  • Ya true Strings are treated differently but substring method will have a reference to original string right.?? so will not prevent Original String sample for being garbage collected . – Hero Apr 07 '13 at 01:48
  • I am aware of no reason `substring` would hold a reference to the original object; it is a function, not a first-class object. What it returns can be considered independent of the original object. Is there a deeper concern here that would elucidate what you're getting at? – Nathaniel Ford Apr 07 '13 at 01:51