File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Garbage Collection for String. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Garbage Collection for String." Watch "Garbage Collection for String." New topic
Author

Garbage Collection for String.

Rajneesh Kumar Rajput
Ranch Hand

Joined: Feb 25, 2009
Posts: 39
How Java garbage collection works for String? As, java has concept of String constant pool but it should not be a separate memory area and should lie in heap space itself.
So, now does java garbage collection behave something different for String object instances from other type of objects.

I read in one of the SCJP book that that java string objects are created once and stays in memory forever? what that means exactly? Will that never be garbage collected even not being referenced or I interpreted that wrongly?
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8708
    
    6

You're kind of all over the place on this.
There is a "Literal Pool" for strings that you declare in your program. For example:

The string "joe" is ripped out by the compiler, replaced with a symbol and the value moved to the literal pool. The compiler will replace all instances of "joe" with this single reference to the value in the pool, a simple way to optimize memory use. These values are never garbage collected.
Instances of String created at runtime are subject to garbage collection just like every other object.
This topic is more appropriate for the Beginner Forum, so I'll move it.




"blabbing like a narcissistic fool with a superiority complex" ~ N.A.
[How To Ask Questions On JavaRanch]
Rajneesh Kumar Rajput
Ranch Hand

Joined: Feb 25, 2009
Posts: 39
Hi Joe,
Thanks for reply. I see the point and also had idea that Java can use its own hash table kind of implementation easily to replace all occurrences of such String.

But, what I didn't get one thing is in your answer that which String you are referring/saying to be eligible for Garbage Collection? You mentioned that String which are created at run time. Can you little bit explore more how that is exactly different from your String that declared probably at instance level declaration?
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8708
    
    6

The alternative to creating a String instance at compile time and having it in the literal pool is creating it at run time, where it is created in the heap. The reason I didn't give an example is because it has to be a little contrived, like the following:

This code creates 10 String instances having the values "joe0" to "joe9". As soon as these strings are printed out, they are eligible for garbage collection.


Rajneesh Kumar Rajput
Ranch Hand

Joined: Feb 25, 2009
Posts: 39
Seems, that String which are created using = "" goes into pool and if I create String using String s = new String(""), it actually an object.
Might be that concatenation is actually doing new () inside in the implementation that I need to check.

But, Yes thanks to you because I was actually looking for that whether String ever get GC or not. But, they get depends on where they present.
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8708
    
    6

Rajneesh Kumar Rajput wrote:Seems, that String which are created using = "" goes into pool and if I create String using String s = new String(""), it actually an object.

There is no difference between the Strings in the literal pool and the Strings in the heap. They are all instances of the same class: String. The literal pool does not get garbage collected. The heap does.

Rajneesh Kumar Rajput wrote:
Might be that concatenation is actually doing new () inside in the implementation that I need to check.


Concatenation with + actually gets expanded into creating a new StringBuffer (maybe StringBuilder in new JDK's) instance, then append() calls for each +, then finally a call to toString() which creates a new String instance. See here for more on that subject.

Rajneesh Kumar Rajput
Ranch Hand

Joined: Feb 25, 2009
Posts: 39
Joe Ess wrote:
There is no difference between the Strings in the literal pool and the Strings in the heap. They are all instances of the same class: String. The literal pool does not get garbage collected. The heap does.
Rajneesh Kumar Rajput
Ranch Hand

Joined: Feb 25, 2009
Posts: 39
Hi Joe, Yes it may be no difference between String that lies in pool and heap which just created using = "" and new String("") but if you compare equals that comes true but if you call == on both that turns false.

So, they is definitely a difference between both these based on the above situation. So, still you are saying that String which lies in pool never get GC but then how do we tell java to restrict space other if that pool memory is full it can interrupt program. Or there is a way to control that situation or to increase that space by the way what is default space allocated to string memory pool by java?
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8708
    
    6

Rajneesh Kumar Rajput wrote:Hi Joe, Yes it may be no difference between String that lies in pool and heap which just created using = "" and new String("") but if you compare equals that comes true but if you call == on both that turns false.


That is a completely different issue. The equals method in String is declared to compare the value of the two Strings. The "=" operator compares the object references. Have a look at How Equals Works in Java

Rajneesh Kumar Rajput wrote:
how do we tell java to restrict space other if that pool memory is full it can interrupt program.

The literal pool cannot get "full". The compiler creates it by pulling the literals out of your code, so it is a set size when you start your program. It neither grows nor shrinks.
The heap can get full and there are steps you can take to mitigate that.
Rajneesh Kumar Rajput
Ranch Hand

Joined: Feb 25, 2009
Posts: 39
Hi Joe,
I might not explained correctly. I actually was saying that both are different and took an example of == to support.

But, the point is still there is two ways to create a pooled version String one is assign directly like, String s = "some value" and using intern() defined in String.
So, actually is there a difference in both or not or both are same at implementation level.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Joe Ess wrote:The literal pool cannot get "full". The compiler creates it by pulling the literals out of your code, so it is a set size when you start your program. It neither grows nor shrinks.


That's true only if you're talking about the constant pool, which is a region in a .class file. That's for all constants referenced in the class definition, not just strings, so I don't think that's what the rest of this thread has been about.

If you're talking about the String intern pool, that's shared with String's intern() method - which means it certainly can grow. It can also grow if you keep loading new classes into the JVM.

It's also possible for items in the intern pool to be garbage collected, but that's fairly unusual, at least for literals, since such object also have other references from the class definition. You can think of the intern pool as a WeakHashMap - by itself, the intern pool will not prevent GC of its contents. But if there are any other references to a String in the pool, those can prevent GC. And it turns out that such references are maintained by the class in memory, after being loaded by a ClassLoader. So the only way for a literal to get GC'd is for the class to get unloaded. Which in turn requires that the ClassLoader that loaded it is also eligible for GC. Which doesn't happen often in beginner code, but it's not unusual in something like an app server. Bottom line, items in the intern pool can be GC'd, but it's complex and unusual.


"I'm not back." - Bill Harding, Twister
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8708
    
    6

Jim Yingst wrote:
If you're talking about the String intern pool, that's shared with String's intern() method - which means it certainly can grow. It can also grow if you keep loading new classes into the JVM.


In my ranting I forgot about intern() so yea, you are right.
I think what Rajneesh is trying to determine is if there is an implementation difference between objects which can and cannot be GC'd. What I'm trying to say is that the implementation is not different, it is where the instance is created: literal pool vs. heap.
Rajneesh Kumar Rajput
Ranch Hand

Joined: Feb 25, 2009
Posts: 39
jim/Joe,

Yes, joe is correct initially I was trying to determine which version of String can be GCed or not. But, yes looking at your reply I can see that in a typical app server how many instances could be there for class was being unloaded by its loader.

But, yes its seems that defining long/frequent string literals could be very expensive.
Tomaz Lavieri
Greenhorn

Joined: Apr 15, 2009
Posts: 4
Jim Yingst wrote:
Joe Ess wrote:The literal pool cannot get "full". The compiler creates it by pulling the literals out of your code, so it is a set size when you start your program. It neither grows nor shrinks.


That's true only if you're talking about the constant pool, which is a region in a .class file. That's for all constants referenced in the class definition, not just strings, so I don't think that's what the rest of this thread has been about.

If you're talking about the String intern pool, that's shared with String's intern() method - which means it certainly can grow. It can also grow if you keep loading new classes into the JVM.

It's also possible for items in the intern pool to be garbage collected, but that's fairly unusual, at least for literals, since such object also have other references from the class definition. You can think of the intern pool as a WeakHashMap - by itself, the intern pool will not prevent GC of its contents. But if there are any other references to a String in the pool, those can prevent GC. And it turns out that such references are maintained by the class in memory, after being loaded by a ClassLoader. So the only way for a literal to get GC'd is for the class to get unloaded. Which in turn requires that the ClassLoader that loaded it is also eligible for GC. Which doesn't happen often in beginner code, but it's not unusual in something like an app server. Bottom line, items in the intern pool can be GC'd, but it's complex and unusual.


can you all clear this to me.... when all say "string pool" its like say a WeakHashMap, and that WeakHashMap is inside on Heap, and all Strings of pool is inside on Heap too ?

the real object literal String is on Heap, like all other, and a referece to then is on pool ? but like all objects on java, they are on Heap ?

the GC cant collect then, corse, cause the string pool (WeakHashMap) still with a reference on thats object ?

sorry for my english, but i m just try to understand, i see many people saying the literal strings are not on heap, they are only at pool, maby i m wrong but i think all Objects are on Heap include all literal string, the only diferent is the "WeakHashMap" making reference to each unique literal strings...

is that true ? all stay on heap ?


from brazil
Tomaz Lavieri
Greenhorn

Joined: Apr 15, 2009
Posts: 4
no one ??
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Garbage Collection for String.
 
Similar Threads
Memory loss
GabageCollection
Memory Leaks
Java's Garbage Collection
garbage collection