File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Immutability behavior of a String object 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 » Java » Java in General
Bookmark "Immutability behavior of a String object" Watch "Immutability behavior of a String object" New topic
Author

Immutability behavior of a String object

Susan Smith
Ranch Hand

Joined: Oct 13, 2007
Posts: 223
Hello,

I am reading HeadFirst Java and there's one section about String immutability that I'm a little bit confused.

There's one example:


The book says that it's creating ten String objects ("0", "01", "012", "0123", through "0123456789").
In the end s referring to "0123456789"
It says that whenever I make a new String, JVM will put it in String pool.

Ok, this makes sense so far.

But then it says that the garbage collector doesn't go to the String pool. This is where I'm confused.

#1.)
I thought what should happen is more something like this:
1. Create String "0".
2. Create new String "01", "0" no longer referenced by anybody, so it's candidate for garbage collector.
3. And so on.

#2.)
And if what it says is true (garbage collector doesn't go to the String pool), then who clean up all those Strings("0", "01", "012", "0123", through "0123456789").
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24166
    
  30

Originally posted by Susan Smith:

It says that whenever I make a new String, JVM will put it in String pool.



No, it doesn't actually say that. It says that String literals like "0" will be held in the String pool; the Strings you're creating in the loop will not be.


#1.)
I thought what should happen is more something like this:
1. Create String "0".
2. Create new String "01", "0" no longer referenced by anybody, so it's candidate for garbage collector.
3. And so on.


That's true for every time around the loop except the very first time; the "0", being a literal, is in the String pool, so it's not collected. All the other ones are.


[Jess in Action][AskingGoodQuestions]
Susan Smith
Ranch Hand

Joined: Oct 13, 2007
Posts: 223
Ernest, thank you for your reply.

1.)
I think it really does saying that on page 589.
Whenever you make a new String, the JVM puts it into a special part of memory called the 'String Pool'


2.)
That's true for every time around the loop except the very first time; the "0", being a literal, is in the String pool, so it's not collected. All the other ones are.

So even though "0" is no longer referenced by anybody, it will be still around in the memory?
I'm still confused about this. Could you please give me some more explanation?

Thanks again.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2969
    
    9
[EFH]: No, it doesn't actually say that.

It certainly shouldn't say that, but it's possible that it does say it anyway. I recall seeing something similar in the SCJP book by the same authors. Perhaps they mis-stated it the same way in both books. I don't have either book available to check at the moment.

[Susan]: But then it says that the garbage collector doesn't go to the String pool.

That's also not true. Though it is true that strings in the pool are stored in a special area, known as the permanent generation, where garbage collection occurs infrequently - because most of the object there are expected to be around for the life of the JVM, probably. But it is possible for strings in the string pool to be garbage collected, in certain cases. If you're using different classloaders, for example, then when a class is unloaded, String literals from that class become eligible for GC. Or if you simply intern() a lot of Strings, without saving any other references to them - those are also eligible for GC.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2969
    
    9
[Susan]: So even though "0" is no longer referenced by anybody, it will be still around in the memory?

"0" is still referenced by the class definition itself. If anyone calls that method again (or constructor or whatever that code is in) then "0" needs to be available as a constant. It will only go away if the entire class becomes unloaded (as can happen in an application server).
Alan Moore
Ranch Hand

Joined: May 06, 2004
Posts: 262
It really does say that (it's on page 661 of the second edition), but it's wrong. Only String literals like "0" and compile-time constants (i.e., static final String variables) are automatically cached in the String Pool. The strings that are created in the for loop in that example will be eligible for gc as soon as all the references to them go out of scope.
Susan Smith
Ranch Hand

Joined: Oct 13, 2007
Posts: 223
For the String literal, How about if I have something like these in the code?

String literal as argument/ parameter
1.)
2.) |

Those above will be considered String literal?

Or is it only for something like this



-----------------
You also mentioned:
and compile-time constants (i.e., static final String variables)


How about String literal for data member?
Example:
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24166
    
  30

A String literal is any sequence of characters surrounded by double quotes that appears in Java code, no matter where. Every one of your examples includes a String literal. That String is always stored in the String pool, as long as your class is loaded into the JVM.
Susan Smith
Ranch Hand

Joined: Oct 13, 2007
Posts: 223
I found this excellent article: http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html
Susan Smith
Ranch Hand

Joined: Oct 13, 2007
Posts: 223
I think this is very interesting.

It means that it is also the same case with some of the debugging code that I have in some of my programs: or some log4j

I also have a console based program that uses a lot of Pattern objects. If I want garbage collector to collect it, then instead of doing this:

I should do this:
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
Writing new String("lalala") won't encourage garbage collection; the "lalala" literal remains regardless.

I think you are best to forget about garbage collection, and leave the JVM to do it. It is happiest when left to work its own way, and keeping a String or two in memory won't do any harm.
In fact there is a slight performance overhead from creating a new String and garbage collection later which you can avoid by using a String literal straight.

A lot of people think there is no point in writing new String("lalala") ever (well, hardly ever); you just write "lalala".
[ August 01, 2008: Message edited by: Campbell Ritchie ]
Susan Smith
Ranch Hand

Joined: Oct 13, 2007
Posts: 223
This leads me to a question:

Is there any tool I can use to investigate what's actually inside the heap and /or stack?
I want to improve the performance of my console-based program and I'm thinking if I can know what's inside the heap and/ or stack, I can get more clear picture of what's going on underneath.
Susan Smith
Ranch Hand

Joined: Oct 13, 2007
Posts: 223
I've tried using JConsole but it doesn't tell me what's inside the heap and/ or stack.
It only tells me the memory usage.
Carey Evans
Ranch Hand

Joined: May 27, 2008
Posts: 225

Try VisualVM from the very latest Sun JDK 6.
Susan Smith
Ranch Hand

Joined: Oct 13, 2007
Posts: 223
(1.) Thank you. I will try VisualVM.

(2.)
Is doing String manipulation best done using StringBuffer than String?
Will it save memory?
For example, I have a lot of replaceAll statement like this below in my code:
Bill Shirley
Ranch Hand

Joined: Nov 08, 2007
Posts: 457
Use a StringBuilder if execution time is important.

sb.append("foo")
or
s = s + "foo"

still create the string literal "foo"

(I would define a string literal simply as "any string the COMPILER sees". It's the part of the in-memory code image, so cannot be "collected".)


Bill Shirley - bshirley - frazerbilt.com
if (Posts < 30) you.read( JavaRanchFAQ);
Alan Moore
Ranch Hand

Joined: May 06, 2004
Posts: 262
Originally posted by Susan Smith:
(2.)
Is doing String manipulation best done using StringBuffer than String?
Will it save memory?
For example, I have a lot of replaceAll statement like this below in my code:

If you're doing several related replacements, you should definitely try do them all in one pass instead of calling replaceAll() several times. The Matcher class contains lower-level methods you can use to accomplish that. For example, if you wanted to replace all of the strings "eastbound", "westbound", "northbound" and "southbound" with their abbreviations, you could do this: (Note that I only used StringBuffer because that's what the methods expect; ordinarily I would use a StringBuilder.)

For a simpler and more flexible way to do this kind of thing, you can use Elliott Hughes' Rewriter. It's essentially a pre-packaged version of what I just wrote.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Immutability behavior of a String object
 
Similar Threads
GC
[eckel] on string initialization
String Object and GC
GC'ing String Constrants
garbage collection