jQuery in Action, 3rd edition
The moose likes Java in General and the fly likes String literals and memory. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "String literals and memory." Watch "String literals and memory." New topic

String literals and memory.

Aron Daburn
Ranch Hand

Joined: Mar 18, 2007
Posts: 36
Once a String literal gets referenced by the constant pool, does it ever get taken out of memory? Possibly such as the class it was coded in gets GC'ed and the class which created the String literal is no longer in the heap? Or is it that once the String literal reference is in the constant pool, there is always a reference to the String so it is always taking up memory?

I'm dealing with a memory sensitive application so any info on this matter would be much appreciated.
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
According to this JavaRanch FAQ the string literals are never ever GC'd. Not even when all classes that refer to them have gone and no other references refer to them.

I guess it's difficult to see how it could be any other way.
[ May 02, 2007: Message edited by: Peter Chase ]

Betty Rubble? Well, I would go with Betty... but I'd be thinking of Wilma.
Jim Yingst

Joined: Jan 30, 2000
Posts: 18671
Unfortunately, the article is not correct in this respect - string literals (and other Strings in the intern pool) can be collected. But it requires unusual circumstances. Before the literal String can be collected, the class that uses the literal must itself be collected. And most ClassLoaders keep a reference to each class they load. So generally the class can't be collected unless first the ClassLoader that loaded it is collected. If you're not using multiple class loaders, this won't happen. But in an environment like an application server, it happens quite routinely when an application is reloaded.

More generally: using Sun's JDKs (all the versions I'm aware of), if a String got put in the intern pool by the intern() method, it can be garbage collected as soon as any other references to the String are removed. The intern pool is roughly equivalent to a WeakHashMap, and does not prevent garbage collection as long as no other references exist. Pooled strings will have been placed in a section of the heap known as the "permanent generation", however this name is misleading. It means that objects in this area are expected to live a long time, usually for the life of the JVM, and therefore garbage collection here is infrequent compared to other parts of the heap. However, that doesn't mean it never happens. Using standard Sun JDKs, it can and does. This behavior is not guaranteed though, so it could change for some future JDK, or a JDK from some provider other than Sun.

To observe GC of literals, try this:

To make this work, after compiling both classes, you need to move (not copy) file StringLiteralHolder.class into a directory called not_in_classpath. (If the class file were in the standard classpath, it would be loaded by a parent ClassLoader rather than the intended URLClassLoader, and this parent ClassLoader would not be collected.) Using System.identityHashCode(), we can observe that the class gets loaded by two different ClassLoader instances, and the field literal refers to two different String instances.

This only works because the class gets completely unloaded, and the String referenced by the literal gets collected, before the class is reloaded. No overlap. If the class had been reloaded by a second ClassLoader while the first was still loaded, we could get a second Class instance for a duplicate copy of the class -- but the literal in the second class would refer to the same pooled String instance. There is only one String intern pool, even with multiple classloaders.

"I'm not back." - Bill Harding, Twister
Peter Chase
Ranch Hand

Joined: Oct 30, 2001
Posts: 1970
Is there anything you can do about that misleading article? I took it that an article on JavaRanch would be "gospel".

Before I read that article, I believed that String literals got GCd when all associated classes did, and that classes could be GCd if there were multiple ClassLoaders. From what you have now written, I guess I was right in the first place, yes?
[ May 03, 2007: Message edited by: Peter Chase ]
I agree. Here's the link: http://aspose.com/file-tools
subject: String literals and memory.
It's not a secret anymore!