Is it good practice to use java.lang.String.intern()?
I have recently written an article about String.intern() implementation in Java 6, 7 and 8: String.intern in Java 6, 7 and 8 - string pooling.
I hope it should contain enough information about current situation with string pooling in Java.
In a nutshell:
- Avoid
String.intern()
in Java 6, because it goes into PermGen - Prefer
String.intern()
in Java 7 & Java 8: it uses 4-5x less memory than rolling your own object pool - Be sure to tune
-XX:StringTableSize
(the default is probably too small; set a Prime number)
String.intern()
is definitely garbage collected in modern JVMs.
The following NEVER runs out of memory, because of GC activity:
// java -cp . -Xmx128m UserOfIntern
public class UserOfIntern {
public static void main(String[] args) {
Random random = new Random();
System.out.println(random.nextLong());
while (true) {
String s = String.valueOf(random.nextLong());
s = s.intern();
}
}
}
See more (from me) on the myth of non GCed String.intern().
When would I use this function in favor to String.equals()
when you need speed since you can compare strings by reference (== is faster than equals)
Are there side effects not mentioned in the Javadoc?
The primary disadvantage is that you have to remember to make sure that you actually do intern() all of the strings that you're going to compare. It's easy to forget to intern() all strings and then you can get confusingly incorrect results. Also, for everyone's sake, please be sure to very clearly document that you're relying on the strings being internalized.
The second disadvantage if you decide to internalize strings is that the intern() method is relatively expensive. It has to manage the pool of unique strings so it does a fair bit of work (even if the string has already been internalized). So, be careful in your code design so that you e.g., intern() all appropriate strings on input so you don't have to worry about it anymore.
(from JGuru)
Third disadvantage (Java 7 or less only): interned Strings live in PermGen space, which is usually quite small; you may run into an OutOfMemoryError with plenty of free heap space.
(from Michael Borgwardt)
This has (almost) nothing to do with string comparison. String interning is intended for saving memory if you have many strings with the same content in you application. By using String.intern()
the application will only have one instance in the long run and a side effect is that you can perform fast reference equality comparison instead of ordinary string comparison (but this is usually not advisable because it is realy easy to break by forgetting to intern only a single instance).