This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Garbage collection & string literal pool Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Garbage collection & string literal pool" Watch "Garbage collection & string literal pool" New topic
Author

Garbage collection & string literal pool

Soumy Kumar
Ranch Hand

Joined: Nov 02, 2004
Posts: 78
How many objects are eligible for garbage collection once execution has reached the line
labeled Line A?



Answer: a

How??


SCJP 1.4<br />" Something is difficult doesn't mean you shouldn't try, it only means you should try harder "
Vivek Mongolu
Ranch Hand

Joined: Apr 17, 2003
Posts: 42
I think the answer should be B which 1. since "Nick" is the only string object eligible for Garbage collection.
shandilya popuru
Ranch Hand

Joined: Dec 21, 2004
Posts: 95
ya so do i think i.e, "nick" would be eligible for GC


sandy
Martin Mathis
Ranch Hand

Joined: Dec 20, 2004
Posts: 45
Why wouldn't "Nick" sit in the string literal pool happily, like "Jason" and "Frieda?"
ankur rathi
Ranch Hand

Joined: Oct 11, 2004
Posts: 3830
yes Martin is right . String object live in String Literal Pool not in Garbage Collection Pool so no point of garbage collection of String object . They will get destroy when you shutdown your JVM .
Hope it is right & useful .
shandilya popuru
Ranch Hand

Joined: Dec 21, 2004
Posts: 95
so strings in string literal pool are not gc`ed at all(only when u shut down jvm) even when u dont have a live reference to it?
Martin Mathis
Ranch Hand

Joined: Dec 20, 2004
Posts: 45
Check This Out

"Unlike most objects, String literals always have a reference to them from the String Literal Pool. That means that they always have a reference to them and are, therefore, not eligible for garbage collection. "
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
I didn't read your article, but I read your quote from it.
I'm going to bet that it is based on JLS 3.10.5.


This example illustrates six points:

Literal strings within the same class (�8) in the same package (�7) represent references to the same String object (�4.3.1).
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 (�15.28) are computed at compile time and then treated as if they were literals.
Strings computed 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.


Unfortunately, this is not the case, at least with the Sun reference implementation. Also, a String instance, which is created for a String literal, certainly does get garbage collected (or at least, could be as per usual garbage collection rules).


Tony Morris
Java Q&A (FAQ, Trivia)
ankur rathi
Ranch Hand

Joined: Oct 11, 2004
Posts: 3830
So , whats the final answer for that question ?

thanks .
Animesh Shrivastava
Ranch Hand

Joined: Jul 19, 2004
Posts: 298
The final answer should be "a", because no objects are being created in the heap,
if the statement is like
String newName = new String("Nick");

Then it would have made us think as here a string object is created in the heap.
ankur rathi
Ranch Hand

Joined: Oct 11, 2004
Posts: 3830
yes & in this case there are two objects getting created , one is on GCH & one is on SLP , so one will be eligible for GC if we assign null to this reference .
Animesh Shrivastava
Ranch Hand

Joined: Jul 19, 2004
Posts: 298

yes & in this case there are two objects getting created , one is on GCH & one is on SLP

After reading the article given in the link as suggested by Martin Mathis,
it says that the SLP is a pool of references, not object.
So, how can
String newName = new String("Nick");
create two objects, it should be only one and that in the heap,

please explain this?
Subhash Bhushan C
Ranch Hand

Joined: Jan 27, 2005
Posts: 106
Case 1:
String s = "First String";

Objects Created in GCH : 1
Is Reference in SLP? : Yes
Is Reference outside SLP? : No

Result of "s = null" : Nothing.
Reason : To quote from the link as suggested by Martin Mathis -> "Unlike most objects, String literals always have a reference to them from the String Literal Pool."

Case 2:
String s = new String("First String");

Objects Created in GCH : 2
Is Reference in SLP? : Yes
Is Reference outside SLP? : Yes

Result of "s = null" : Object in GCH with reference outside SLP is destroyed.
Reason : The Object with reference in SLP is preserved, and reused as long as JVM is up. But the object in normal(nonpool) memory is marked eligible for Garbage Collection. The String object with literal "First String" will be kept in SLP and whenever another string object is created like this, String s = "First String";, the same reference will be passed to point to this object.

Hope I make myself clear.


Regards,<br />Subhash Bhushan.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
The correct answer is B.

A String instance is created for String literals (on the heap as per usual).
An object is not created for String literals for the "String literal pool", which is a mere abstraction, and does not physically exist.

Am I repeating myself in this forum or is time standing still?
[ February 01, 2005: Message edited by: Tony Morris ]
Steven Bell
Ranch Hand

Joined: Dec 29, 2004
Posts: 1071
I beg to differ.

The answer is A. There is no String available for GC. The 'String Literal Pool' is part of the spec, not just an abstraction.

I do not believe that new String("Whatever"); creates two Strings. If you use new to create a String it is a distinct String and is eligable for GC, but as far as I can tell it is not required to be interned.

If someone can point to the spec where I'm wrong on that, let me know.
Jay Pawar
Ranch Hand

Joined: Aug 27, 2004
Posts: 411
I agree with Steven and would stick to choice "a" as my answer. Here is the excellent
article by Corey which explains about the Strings and their GC behaviour.
[ February 01, 2005: Message edited by: Jay Pawar ]

Cheers,<br />Jay<br /> <br />(SCJP 1.4)<br />Heights of great men were not achieved in one day, they were toiling day and night while their companions slept.
Mike Gershman
Ranch Hand

Joined: Mar 13, 2004
Posts: 1272
I rechecked K&B carefully and I just don't believe the SCJP exam has questions based on the actions of the Garbage Collector dealing with the String Constant Pool. Too much of this stuff is implementation dependent.

Kathy or Bert can correct me.

BTW, I would choose answer a.


Mike Gershman
SCJP 1.4, SCWCD in process
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608

Although that's close, it's not exactly correct. Really, it's a collection of references to String objects


This statement on the article, like most others on this thread, assume that JLS 3.10.5 is correct (in my opinion, it is actually ambiguous and has two possible interpretations).

The reference implementation (Sun) has no such concept as a physical literal pool. I believe it is also possible to interpret the JLS this way.
That said, there are two possible scenarios:
1) The JLS is incorrect - the reference implementation is a better demonstration of "how things should be". The JLS made certain assumptions that didn't hold true.
2) The JLS is ambiguous and most people interpret it as its incorrect meaning - the reference implementation clears up any ambiguity.

I tend to lean towards 2) - but in both cases, there is no physical String literal pool or "reference pool" or <insert-dreamt-up-term-here/>.

A new object is created for each literal - it may, or may not be the same instance that is used on String literals (or any compile-time expressions) that have the same value. This is either contrary to or an ambiguity in JLS 3.10.5.


If someone can point to the spec where I'm wrong on that, let me know.


The ambiguity in the spec. is in JLS 3.10.5

Here's the proof (with an exercise for the ill-informed reader):



Prove beyond all doubt that the String instance (yes that's right i-n-s-t-a-n-c-e) that is referred to by s1 and the one referred to by s2 may or may not be the same instance. You will need to somehow convince the garbage collector to run (brute force) and determine a strategy for identifying the unique identity of an object instance (hint: java.lang.System).

Once you have achieved this, you can draw 2 conclusions:
1) A String literal certainly does have an instance created during runtime (so where is this String literal pool that all these people speak of? in their head perhaps?)
2) Two String literals may not be referring to the same instance even if they have the same value (JLS 3.10.5 has an ambiguity or is incorrect).

I hope this clears it up.

<repeat value="false"/>
</rant>
[ February 01, 2005: Message edited by: Tony Morris ]
Steven Bell
Ranch Hand

Joined: Dec 29, 2004
Posts: 1071
I've run this several times and the two always have the same hashcode, (well, it changes between iterations, but you know what I mean). Can you show an example where two String constants show up as different objects?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Tony- umm, I agree with Steve, but more importantly at the moment: don't edit your last post! There's an unfortunate bug in UBB which causes it to occasionally eat portions of posts when you edit them. Specifically, it's set off when you mix [ quote ] and [ code ] tags in the same post - the lines in between the two are removed. It looks like this has happened once already (based on the closing </rant> tag with no opening tag), and if you edit the post again it will probably happen again (since there's still another [ quote ] and [ code ] in there). So - don't touch that post! (Unless you first copy the contents to a copy buffer or elsewhere, so you can reconstitute the original.) Sorry ' bout that.


"I'm not back." - Bill Harding, Twister
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Mike: yeah, for anyone whose primary interest is in simply taking the SCJP exam, rather than esoterica which aren't on the exam: the real exam will not have any questions which depend on knowing about the string pool and whether or not String literals are eligible for GC. The test authors have deliberately avoided this issue because it's way too nitpicky, even for them. Now mock exams may well ask questions which require this knowledge - but the real exam will not.
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
So much has been said, and so many contradictory opinions that I think Soumy will never now which one is the right answer.

However I will do my part saying my opinion.



1. The declaration does not point to any object. Variables is not initiliazed yet.
2. "Nick" is stored in the Literal Pool String, two object references point to it (newName reference object and the Pool String reference object)
3. "Jason" is stored in the Literal Pool String, two object references point to it (newName reference object and the Pool String reference object, the Nick string is now referenced just by the Pool String so it is not elegible for GC, and will never be)
4. "Frieda" is stored in the Literal Pool String, two object references point to it (name and Pool String)
5. Now another object points to "Frieda", thats to say newestName
6. Now name does not point to "Frieda", so just two object point to "Frieda", newestName and the Pool String.

Conclusion

What object are elegible for GC?
Answer: None.

All string are yet refenced by the Pool String and they will never be elegible for GC, period.
[ February 01, 2005: Message edited by: Edwin Dalorzo ]
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608

All string are yet refenced by the Pool String and they will never be elegible for GC, period.


For your sake, can you please tell me where you think this "Pool String" lives? ...and how did you conclude that objects that are created for String literals are never garbage collected?

Let's make it a little easier:



Prove that X.s and Y.s can refer to two different instances during runtime.
It can be done. Note that both are compile-time constant expressions (JLS 15.28) and so are inlined at compile-time.

On the note by Jim, this is not tested in the SCJP exam.
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Hi, Tonny.

I tested this code:



This is the output:
true
true

So, is it or is it not the same String object?
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Now I quote the JLS 2nd Edition 3.10.5


� Literal strings within the same class (�8) in the same package (�7) represent references to the same String object (�4.3.1).
� 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 (�15.28) are computed at compile
time and then treated as if they were literals.
� Strings computed 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.
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Regarding the Garbage collection afair the conclussion was not my invention. I read in the article recommende above:




Check this out
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
There is also a chapter on the subject in the Java Virtual Machine Specification 5.4. un String Resolution.
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Finally, Tony


...prove that X.s and Y.s can refer to two different instances during runtime...




The output is:
false
true
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
The article that was provided makes many false claims much to its discredit. I choose not to use it as anything more than misleading fallacy and so only skimmed your diagram.

In case 1, you proved that the two references may refer to the same instance - this was never an issue - in the case you have provided, they will always refer to the same instance.

What was asked is to prove that they may not refer to the same instance (i.e. provide that case).

In case 2, you altered my code - the test case is flawed.

I am trying to invoke some thought on your behalf - if you really insist, and since I've spent more time quashing the untruths on this thread, I might as well spend the time and write the proof ... but I'll wait for some lateral thinkers to have a go first.

Until then, I will continue to assert that an object is created for a String literal during runtime and may certainly be garbage collected as per usual garbage collection behaviour. Also, two String literals that have the same value do not necessarily exist as runtime instances in the way that JLS 3.10.5 ambiguously (erroneously?) suggests. The "String literal pool" is merely an abstraction that does not physically exist. If you are having trouble removing this from your imagination, please consider the following, very simple scenario:



How then, according to the "String literal pool" does this scenario exist? I'm curious as to what the imagination can dream up for this simple case.
Also, for those who falsely believe that no object instance exists, just what does s refer to? ...and for Object o = "x"; just what does o refer to?

I think I've exhausted this one - if you really choose to go on believing what you choose to do, whether it be fallacy or not, so be it. My next post will be proof when I can be bothered providing it.
[ February 01, 2005: Message edited by: Tony Morris ]
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
I might be having some difficulty understanding your English, Tony. I do not see what is the point. Far away from a discussion I would like to see the truth. What what you want to prove? What am I contradicting you?

I quote the Java Language Specification:


20.12.47 public String intern()

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 method (�20.12.9), 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 (�3.10.5).



This text is also present in API documentation for String under the intern method.

My conclusion is that as Strings literals are mantained in string pool of the String class, string objects won't be elegible for garbage collection until String class is unloaded.

Strangely the intern method of the class String is declared native and we cannot see the implemention of the method in the API. For some reason the API does not says the method is native. I have not found much information regarding what exactly is the string pool besides this. I gues the jvm handles this string references in some sort of structure bound to the class String. But of course, I have not based this information in any trustable source.

So what all this mean if the so-called string pool really do no exist? What are you basing to say that the article posted on the Java Ranch is incorrect? Because we just can trust you, as you can just trust me? I did not write Java, did you?
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Furthermore, Tony. I do not know what version of the JDK you are using. But this code:



Prodocues the output false. The JLS says the + operator produces a new String (JLS 15.18.1)

So what do you mean? Is Your sample code flawed?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[B][Tony]: The "String literal pool" is merely an abstraction that does not physically exist. If you are having trouble removing this from your imagination, please consider the following, very simple scenario:

How then, according to the "String literal pool" does this scenario exist?[/B]

Dunno, since your code doesn't compile as written. If I replace "s1" with "s", it prints false, not true. (I'm running JDK 1.5.0_01 on Windows 2000 Pro, so if you get a different result, please let me know what you're running on.)

Now, if I make one further change and make s a final variable, we get results like you describe:

I'm curious as to what the imagination can dream up for this simple case.

No need for imagination - it's pretty much spelled out in the JLS, JVM spec, and the String API. The "lah" and "blah" are string literals of course. As such, they're required to be interned in the string pool. And now c and s are compile-time constant expressions, which means (c + s) is also a conpile-time constant expression, which means that its result ("blah") is also interned, and since that's already been interned, (c + s) is guaranteed to return a reference to the same string that the "blah" literal refers to.

Now if we were to use javap and look at byte codes, we might verify that most of the work for this was done at compile time rather than run time, and thus you might want to argue that the string intern pool doesn't need to exist at runtime. Well then - what happens if we add the following statements to the previous snippet?

On my system, these print false and true, respectively. I would assert that the latter is possible only because (c + s) has indeed been interned on the very string pool which you say does not exist. So now I'm curious - how would you explain this?

Also, for those who falsely believe that no object instance exists, just what does s refer to? ...and for Object o = "x"; just what does o refer to?

For the record, I fully agree with you that references s and o refer to instances of the String class. No disagreement on that one.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
On the first case, sorry - I just banged it out without looking back - you guessed correct at the intention.

On the second case, since when were we talking about a String pool? I thought this was a "String literal pool"? It can be argued that a String literal physically exists in bytecode - is this the elusive "String literal pool"?

Interned Strings exist in memory.



What now?
[ February 01, 2005: Message edited by: Tony Morris ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Hi, Edwin.

[Edwin]: Strangely the intern method of the class String is declared native and we cannot see the implemention of the method in the API. For some reason the API does not says the method is native.

What's strange about this? I don't believe javadocs ever tell us if something is native. (Am I wrong? Maybe there's an option somewhere to force this.) That's an implementation detail, not something we need to know in order to use the code.

Previously Tony has alluded to the reference implementation - that can be found here. Among other things, it contains C code for all the native methods in the statndard Java libraries. Unfortunately it's a rather large and unwieldy amount of code for me to digest, and my C skill are quite rusty at this point. But it Tony wants to point out specific files which deal with how string literals are handled, or how the intern() method works, I'm willing to do more work to understand them.
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Hi, Jim.

Thanks for your comments. I will give it a look to the C code one of these days. I guess, anyway, at the end of all this, that's not so important for SCJP 1.4.

It's 12:30 in my country now and I am bit tired, so I am affraid Tony I will not be able to run and see your code tonight. Still I have to install JDK 1.5. I do not even know if it is going to behave different.

I will give it a look and maybe tomorrow I will post something on the subject.

Good night to you all, guys!

PD.

I just would like to ask you, Tony. What should I pass to the program in the command line so that the program runs?, because If it does not receive any argument I get an IndexOutOfBoundsException, obviously

[ February 01, 2005: Message edited by: Edwin Dalorzo ]
[ February 02, 2005: Message edited by: Edwin Dalorzo ]
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
Ok. Tony. I tried this:

javac Main.java

It compiled with JDK 1.5


Now I tried this:

java -cp . Main X.class Y.class

And I get this:


What Am I doing wrong? I am a beginner and I am not experienced with reflection.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
since when were we talking about a String pool? I thought this was a "String literal pool"?

Speaking for myself, I've generally been talking about what I refer to as the String intern pool, which is also used by String literals (as shown in my code in the next-to-last post I made). I've been assuming that most others here were referring to the same thing, though we seem to have different concepts about how it operates. Maybe that's a false assumption.

It can be argued that a String literal physically exists in bytecode - is this the elusive "String literal pool"?

That's not what I've been referring to, though I did mention its existence in one of my previous posts.

Like Edwin, I've got to get to sleep shortly, so I don't have time to diagnose exactly what's going on in your code just now. My initial guess would be to say that each classloader probably has its own intern pool. Which may indeed be an ambiguity in the JLS, or not - will have to look some more. Thanks for providing a more concrete example of what you're talking about though. Cheers...
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Edwin- try running with

java Main .

The URLClassLoader expects arguments forresponding to the base directories and/or jar files which your class definitions reside in. So if your class foo.bar.Test resides in a class file at /home/edwin/javastuff/src/foo/bar/Test.class, you need to pass in the path to the base directory /home/edwin/javastuff/src. (The foo and bar are inferred from the package name.)

Incidentally I found that when I ran inside IntelliJ (my usual default) I always got the same result for both hash codes - it's only when I ran java from the command line that I got different results. Interesting - probably IntelliJ is performing its own manipulations with class loaders, interfering with the results. Worth noting for anyone else running within an IDE.

Now really, I am going to bed.
[ February 02, 2005: Message edited by: Jim Yingst ]
Edwin Dalorzo
Ranch Hand

Joined: Dec 31, 2004
Posts: 961
I am afraid I could not go to bed with the doubt. Tomorrow is going to be a long day.
However I think I have an explanation for Tony's algorithm.
I quote the JLS 12.7

An implementation of the Java programming language may unload classes. A
class or interface may be unloaded if and only if its defining class loader may be reclaimed by the garbage collector as discussed in �12.6. Classes and interfaces loaded by the bootstrap loader may not be unloaded.


That means Tony's classloader is being reclaimed by the GC. Then String class is unloaded and string pool is destroyed or reclaimed by the garbage collector after no references from the string pool remain active.

I changed slightly the Tony's code so that classloaders are not elegible for GC and you will see the strings are obtained from the string pool, just the way the sample code without reflection.



I receive this output:
32942009
32942009

That means, Tony, that the String pool does exist!!!
[ February 02, 2005: Message edited by: Edwin Dalorzo ]
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
As we confirmed earlier, when I post some code, and you change it, you may or may not get different results - sorry to state the obvious.

Also, in the case I posted, the garbage collector is not guaranteed to clean up the String instance. If it does, you will not see the same identity hash code.

I have no idea how you concluded that the String pool does not exist because you modified my code and saw a different result. That is to say, the statement, 'I changed your code to System.out.println("Hello world"); and I saw Hello world, therefore, typewriters do not exist.' makes no sense to me and is directly analogous to how I interpret your (once again) false claim. Seriously, I'm over it.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Garbage collection & string literal pool
 
Similar Threads
garbage collection question
Garbage collection
Garbage Collection????
GC question
doubt on garbage collection