File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes String Pool Redux Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "String Pool Redux" Watch "String Pool Redux" New topic
Author

String Pool Redux

Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
Ok, this issue of string pool allocation objects has been wearing on me so I decided to write a little test program to see if these objects are in fact ever garbage collected. Guess what? They are!

This program runs in an endless loop continuously creating a unique string, then adding that string to the string pool. Every 10,000 new strings, it prints out a diagnostic message showing the total memory for the VM and the free memory available. You'll notice if you run this that the free memory fluctuates,but never gets below around 25 %. Garbage collection is clearing these string pool objects!!
To verify that objects are really being created you can uncomment line 1. This adds the string to an ArrayList, thus keeping a strong reference to the object, preventing it from being garbage collected. If you do this, you will run out of memory.
This test application shows that java does in fact clear out the string pool during garbage collection; as long as no objects are referencing an object in the string pool, they get treated like any other object that is not referenced-they become eligible for garbage collection.

Rob "string literal mystery solver"


Rob
SCJP 1.4
Roy Ben Ami
Ranch Hand

Joined: Jan 13, 2002
Posts: 732
amazing Rob!
well done.
thanks for solving this mystery
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5370
Hi Rob
Thanks a lot.
I think question was from the Exam view of point and for normal small peiece of code like this
1. public void process(int count) {
2. for ( int i = 1; i < count; i++ ) {
3. Object temp = " Hello "+i; }
4. }
do we have to consider the GC of string litral as you can see by running your program that after capaturing(creating objects) lot of memory it is freeing String litrals.
and if we are going to consider GC of litrals then what abt StringBuffer which are being created internally .
So I think from the Exam point of view answer should be 4.
CMIW


"Thanks to Indian media who has over the period of time swiped out intellectual taste from mass Indian population." - Chetan Parekh
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
newString.intern() is not a string literal.
The program shows that string objects that are interned are g.c.ed
The code that shows how string literals are not g.c.ed is here:
www.javaranch.com/ubb/Forum24/HTML/012708.html
Your program is interesting because shows that a programmer can not run out the heap by interning many string objects.
Later I will post a program to see how "Hello".intern() behaves


SCJP2. Please Indent your code using UBB Code
Shivaji Marathe
Ranch Hand

Joined: Jan 11, 2002
Posts: 203

Rob "string literal mystery solver"

Very TRUE. Great program Rob. Now we can lay this topic to rest!
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5370
Originally posted by Jose Botella:

newString.intern() is not a string literal.

but I think it put your this stirng in litral pool if not available.
CMIW
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
First of all, I think we are splitting hairs.

Second I don't expect questions regarding the reachability of string literals in the exam.
Third. String literals are not g.c.ed
Fourth. newString.intern() is not a string literal. It places a string object in the string pool.
Rob's program shows that these object though in the string pool are g.ced
Thanks Rob, I din't know that
This program shows that String literals that are computed at compile time (JLS 15.28) are not g.ced

The string literal is always reachable, though you can see sucessives g.c.tions if you run like "java -verbose:gc Test" When the strinCount reaches 200000 I expect the first string object is already g.c.ed It is, because it prints null. My intention was to demonstrate how the weak reference doesn't prevent an object of being g.c.ed
My conclusion is that string literals are not g.c.ed but others string objects, even in the pool, are.
Also be careful with this:

Is there anyone still confused , just remember the first two points of this post
[ January 21, 2002: Message edited by: Jose Botella ]
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
Jose,
I was just about to respond when I saw you have posted a long test program, so I haven't looked at it yet, but I will.
The main confusion I am having about the "string pool" is that there seems to be two of them, one for interned strings, and one for string literals, even though I can't find *any* literature that explains the difference. Even the javadocs for the String.intern() method suggest there is only one pool...

intern
public String intern()
Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.
All literal strings and string-valued constant expressions are interned. String literals are defined in �3.10.5 of the Java Language Specification
Returns:
a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.


If what you are saying is true, it seems the javadoc for String.intern() is incorrect?
I'll look at your new program later today and comment later

Rob
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5370
Hi Jose
as u say .. no more splitting hairs
so answer is 4 ahahaha
I don't expect questions regarding the reachability of string literals in the exam

agreed


FOR a time being .... if possible then anyone
what is going on here

what is the difference betn LINE 01 and LINE 02.
would luv to hear from jose.
(Yes it can be put in to Adv Java, but then you should provide some mechanism to get informed to other threads also if some reply comes.)
TIA
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5370
Originally posted by Rob Ross:
Jose,
The main confusion I am having about the "string pool" is that there seems to be two of them, one for interned strings, and one for string literals, even though I can't find *any* literature that explains the difference.
Even the javadocs for the String.intern() method suggest there is only one pool...

No.. doc just says they are interned
I think they two places for String pooling.. one for String litral and one String constants(generally which appear betn S.o.p)
CMIW


If what you are saying is true, it seems the javadoc for String.intern() is incorrect?

this might be the case plz see
I checked source .... intern is native method!!!
but still I think ans is 4
[ January 22, 2002: Message edited by: ravish kumar ]
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
to Rob
I don't mean API for intern is wrong.
I don't really know if there are two string pools.
I only state that string literals and String expressions computed at compile time (JLS 15.28) are not g.c.ed

to Ravish
I don't mind splitting hairs with any well-mannered Rancher in pursuit of Java knowledge.

Hey, you forgot making str01 null
For completness I am posting this code

According to JLS 15.28 "Hello " + j is a constant expression computed at compile time. They are not g.c.ed
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
All literal strings and string-valued constant expressions are interned
That's from the JavaDoc for String.intern();
It states right there that literal strings are interned!
So if you are correct Jose, it means that there is one of three explanations:
1. a special literal intern pool exists seperate from the "regular" intern pool, that I can't find any documentation for
2. this java doc is wrong and literals are not interned; something else happens to them
3. string literals in the intern pool have some special, "magical" state that prevents them from being gc while other strings in the intern pool created with String.intern() can be gc.
I don't like any of these alternatives only because I can't conclusively prove which one is actually the case.
But your code example supports your statement that string literals aren't gc. Of course, being the scientist, I can't say it *proves* your point, only that it supports it. However, I am now leaning towards the side of thinking that string literals exist for the life of the program. But this still leaves me with the above unanswered questions.
I need to *know* this, not just take it on faith!
Thanks for your input so far!
Rob
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5370
I got it ..........
I am assh@#$...
but Jose you too....

I only state that string literals and String expressions computed at compile time (JLS 15.28) are not g.c.ed

and what so ever is being GCed are interned at runtime as stringCount or what so evar variable we are concating .... so interned at RUNTIME could be GCed.
Now I am 100% sure that COMPILE time string litrals are not GCed BUT RUNTIME string litrals are GCed
as you said Jose it is there in (JLS 15.28) (I have not checked)...
CMIW
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
Hello everybody
I have the answer at last.
String literals and String objects computed from constant expressions (JLS 15.28) are not g.c.ed becuase a reference is hold to them in the constant pool of the class that declares them. Thus even seeting all the programmers reference to null they will keep on being pointed to by the constant pool as long as the class data is loaded.
To check this I have written a class that creates several of these objects:

At lines 10, 16, 0 and 3 you can see ldc# 3, 5, 7 and 8 bytecodes. They load the reference to a string object from the constant pool to the operand stack. Thus entries 3, 5, 7 and 8 in the constant pool are to blame for the almost permanet reachability of these kinds of objects. Well, permanet? not really. We can download the class Test2, and doing so its constant pool disappears. Now these objects are g.c.ed
This progrma shows it:

I have not more time now. I am going to my dancing classes
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
I forgot to mention that Test2.class is in "other" directory, under the current one where Test.class is executed.
Rob Ross
Bartender

Joined: Jan 07, 2002
Posts: 2205
Hey good work Jose.
I had just read up on how to unload a class by using a custom class loader!
But you are right...every .class file has a private constant table, and for string constants, they are references to a String object in the string pool. So you are correct, as long a class is loaded, all string literals used by that class create a strong reference to a String object in the pool and thus never are eligible for gc.
I finally feel I have a good understanding of how this works.
The important issue is that in code, a string literal is just the constant string expressions that can be computed at compile time.
String myString = "I am a string"+" composed of two segments, but I am one string literal";
int i = 5;
String aString = "This is a string literal "+i;
aString above, is NOT a string literal because its value must be computed at runtime. There is only one string literal above, and that is the text between the quotes.
Anyway, thanks for shedding light on this matter once and for all Jose!
Rob
R K Singh
Ranch Hand

Joined: Oct 15, 2001
Posts: 5370
Originally posted by Rob Ross:

String myString = "I am a string"+" composed of two segments, but I am one string literal";
int i = 5;
String aString = "This is a string literal "+i;
aString above, is NOT a string literal because its value must be computed at runtime. There is only one string literal above, and that is the text between the quotes.
Anyway, thanks for shedding light on this matter once and for all Jose!
Rob

that's what I said ....
I like this thread ...Jose I will check your prog soem other day...
till then
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: String Pool Redux
 
Similar Threads
JVM process memory never comes down
GC doubt
Help, java memory leak somewhere!!!
ObjectInputStream creating OutOfMemoryError
System Information Code not running