7
String str1="JAVA";
String str2="JAVA";
String str3=new String("JAVA");
String str4=new String("JAVA").intern();

2 objects will be created. str1 and str2 refer to same object because of String literal pool concept and str3 points to new object because using new operator and str4 points to the same object points by str1 and str2 because intern() method checks into string pool for string having same value.

str1=str2=str3=str4=null;

One object will be eligible for GC. That is the object created through String str3=new String("JAVA"). The first String object is always accessible through reference stored in string literal pool.

Is my explanation correct?

Gajanan Kulkarni
  • 697
  • 6
  • 22

1 Answers1

12

Total Number of String objects created in the process?

Three: The one in the intern pool created via the literal and the two you create via new String.

One object will be eligible for GC.

I count two, and possibly even all three under very special circumstances:

  1. The one you created in this line:

    String str3=new String("JAVA");
    

    (since you later set str3 to null).

  2. The one you created temporarily in this line:

    String str4=new String("JAVA").intern();
    

    That line creates a new String object, calls intern on it, and then saves a reference to the string from the pool. So in theory, it creates a String object that is immediately available for GC. (The JVM may be smart enough not to do that, but that's the theory.)

  3. Possibly, eventually, under the right conditions, even the string in the intern pool. Contrary to popular belief, strings in the intern pool are available for garbage collection as we can see from the answer to this other question. Just because they're in the permgen (unless you're using Oracle's JVM 7 or later) that doesn't mean they're not GC'd, since the permgen is GC'd too. So the question becomes: When or how is a string literal used in code no longer referenced? I don't know the answer, but I think a reasonable assumption would be: When and if the class using it is unloaded from memory. According to this other answer, that can only happen if both the class and its classloader are unloaded (and may not happen even then). If the class was loaded by the system classloader (the normal case), then presumably it's never unloaded.

So almost certainly just two (#1 and #2 above), but it was fun looking into #3 as well.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • They're all set to `null`. Shouldn't the GC collect them all since all references explicitly set to `null`? – Maroun Jun 29 '13 at 07:18
  • Oh.. didn't notice that :) Time for Coffee. – Maroun Jun 29 '13 at 07:21
  • I heard that interned Strings are also collectable - they are not in perm gem forever – dantuch Jun 29 '13 at 07:22
  • @dantuch: As of one of the recent versions, yes. I forget whether that was 6 or 7. *Edit:* It was 7. – T.J. Crowder Jun 29 '13 at 07:23
  • @T.J.Crowder: Wont there be two objects eligible for garbage collection ? (1)`tring str3=new String("JAVA");` and (2) the nameless object created on heap in code `String str4=new String("JAVA").intern();` – Vishal K Jun 29 '13 at 07:23
  • @VishalK: That's what I said. – T.J. Crowder Jun 29 '13 at 07:24
  • String str="Java "+""+"Learner"; in this process 3 objects will be created because "" would not create new object.am i right? – Jaikant Bhagwan Das Jun 29 '13 at 07:27
  • @T.J.Crowder Yeah..Got that.. Thnx +1..And if all the references are being reachable by strong reference in code..then only and only one object will be eligible for garbage collection and that will be the nameless object created in declaration `String str4=new String("JAVA").intern();`..Right? – Vishal K Jun 29 '13 at 07:30
  • @VishalK: Without the `str1=str2=str3=str4=null;`, yes, just that one temp object. – T.J. Crowder Jun 29 '13 at 07:31
  • as in know String Literal pool is the collection of references to String objecs.so how object will be created in pool? – Jaikant Bhagwan Das Jun 29 '13 at 07:32
  • @JaikantBhagwanDas: There is no "String Literal pool." There's the [intern pool](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern()). The JVM puts string objects for your string literals into the intern pool automatically when loading your class. – T.J. Crowder Jun 29 '13 at 07:38
  • @T.J.Crowder: It will be 3 objects even in jdk 5 and 6. See my post. – Lokesh Jun 29 '13 at 07:43
  • 2
    @T.J.Crowder We shouldn't equate "Java" with "OpenJDK HotSpot JVM", and the details about PermGen and string constants only pertain to the latter (and maybe not even to all its execution modes). There is nothing in Java Specification about this. – Marko Topolnik Jun 29 '13 at 08:08
  • @T.J.Crowder: I've been shown that even in Java 6 interned strings can become GCed. Maybe it has become even more likely in Java 7, but I think it was there before as well. – Joachim Sauer Jun 29 '13 at 08:17
  • @MarkoTopolnik: Quite so. I thought about flagging it up but it seemed overkill. Now I've made the edit, I'm not sure why I thought that. :-) – T.J. Crowder Jun 29 '13 at 11:02
  • @JoachimSauer: Sure enough. The change with JVM 7 just moves the intern pool out of the permgen. But they could be GC'd in the permgen. Thanks! – T.J. Crowder Jun 29 '13 at 11:38