Tuesday, May 20, 2008

Garbage Collection of String literals

Tapan/Saurabh
Your thoughts on this--Does the GC handle the String literals. Since the String literals are interned,Does this mean that GC would not collect these string literals. If it does how/when?
--Ramraj

7 comments:

Saurabh said...

I think the string literal are garbage collected.They remain in the constant pool until the parent class or the child classes which initially refrenced it is being unloaded.

i am not very clear about the String class intern() method.
It says that if we do a
new String("saome string").intern()
it check in the constant pool, if the string satisfy equals method of String class it get the refrence from the string pool..
but is it not defying the menaing of 'new' keyword..which says it creares a new object(or a new memory address)

PLease commesnt dudes...

RamrajChauhan said...

The GC for String literals does happen and the scenario is same as you have said above.
Intern is a native method in String class which has the same functionlity as you have said..

..SAHI JAWAB

RamrajChauhan said...

This statement
new String("saome string").intern()
it check in the constant pool

is not correct. It would check only in case of String literals,but when we say new String("blah blah") we are aksing him to create a new object for that String.

let me know ur comments on this.

Saurabh said...

class TestString
{
public static void main(String[] args)
{

String str = "Saurabh";
String str1=new String("Saurabh");
String str2 = new String("Saurabh").intern();
System.out.println (System.identityHashCode (str));
System.out.println (System.identityHashCode (str1));
System.out.println (System.identityHashCode (str2));
}
}

java TestString
26726999
7494106
26726999

This shows that first and third have the same obj ref.So intern() forces the JVM to do the checking for existing string literal during classloading.

RamrajChauhan said...

yeah this seems good. Intersting.
Missing Tapan Sing's Comments.

Tapan said...

The contract of intern():
First the return type for intern() is String. This method always return the reference to a String object lying in the constant pool of the String class and that String object will be equal in content to the object on which the method is called.

So when you call:
String str2 = new String("Saurabh").intern();

First a String object is created on heap and then intern() is called on that object. The method checks whether there is any String equivalent to this object is lying in the pool:
If yes, it returns the reference to that String object in the pool

If no, it adds the caller String object to the pool: means add a new reference to the pool which points to this String object (on which intern() is called).

Now the gc:
The pool behaves as static field to the String class. You can think of the pool like:

public class String {
//An array may not be the appropriate datastructure for the pool but there should be sth like this.
private static String[] pool;
}

Now when some String object is being referenced to the static pool of String class, it cannot be gced until you unload The String class itself and that will happen only if you unload the class loader which loaded the String class (i.e. bootstrap class loader) which is not possible.

It might be the case that pool keeps checking for the String objects which have no other references in threads' stack and keep lying in the pool for a certain period of time and then purges such objects and that could be the possible scenario for gc of pooled String objects.

RamrajChauhan said...

I feel that the second case mentioned
'Pool keeps checking for the String objects ' would the good case for String objects to be GCed