Thursday, December 14, 2017

When to use intern() method of String in Java?

String.intern() method can be used to to deal with String duplication problem in Java. By carefully using the intern() method you can save a lot of memories consumed by duplicate String instances. A string is duplicate if it contains the same content as another string but occupied different memory location e.g. str1 != str2 but str1.equals(str2) is true. Since String object consumes a large amount of heap memory in average Java application, it makes sense to use intern() method to reduce duplication and take advantage of String pool feature provided by Java. You can use intern() method to intern a String object and store them into String pool for further reuse.

For example, when you create a String literal e.g. "abc", it's automatically stored in String pool, but when you create a new String object e.g. new String("abc"), even though it's same String, a new object at a different memory location is created. This is a duplicate String.

By calling  the intern() method on this object, you can instruct JVM to put this String in the pool and whenever someone else creates "abc", this object will be returned instead of creating a new object. This way, you can save a lot of memory in Java, depending upon how many Strings are duplicated in your program.

You can also read Java Performance by Charlie hunt and Java Performance, The Definitive Guide By Scott Oaks to learn more about troubleshooting Java Performance issue and optimizing the performance of Java applications.

Some important things about String.intern() method

Here are some of the important points about the intern() method from java.lang.String class which are worth remembering:

1) String.intern() method is there in String class from JDK 1.1. It returns a canonical representation of String object. When the intern method is invoked, if the String pool already contains that String object such that equals() return true, it will return the String object from the pool, otherwise it will add that object to the pool of unique String.

2) After calling intern() method on s1 and s2, s1.intern() == s2.intern(), if s1.equals(s2) because both will be pointing same String constant in pool.

3) Prior to Java 6, uncontrolled usage of String.intern() method can cause java.lang.OutOfMemory: PermGen space because String pool was physically located on PermGen area of Java heap, which is quite small in many JVM (32M to 96M) and fixed. From Java 7 onward, the intern()  method has become even more useful because String pool is relocated to main heap space of JVM. This will help to further reduce String duplication by using String.intern() method.

What is intern() method of String in Java

4) The intern() method is a non-static method and should be called using a String literal or String object in Java.

That's all about when to use String.intern() method in Java. Java 8 update 20 also introduced a new feature called String deduplication, which can reduce memory footprint caused by duplicate String without writing a single line of code, but, unfortunately, it's only available for G1 garbage collector and you cannot use it if you are using ConcurrentMarkSweep garbage collector.

Further Learning
Data Structures and Algorithms: Deep Dive Using Java
Java Fundamentals: The Java Language
Complete Java Masterclass

If you want to learn more about the String class in Java, don't forget to read following articles:
  • Why is String made final or Immutable in Java? (answer)
  • How substring() method works in Java? (answer)
  • Why char[] is more secure than String for storing a password in Java? (answer)
  • How String in switch case internally implemented in Java 7? (answer)
  • The right way to check if String is empty in Java? (answer)
  • How to compare two String objects in Java? (answer)
  • How does String concatenation work in Java? (answer)
  • How to escape String literal in Java and Eclipse IDE? (tip)
  • The real difference between String, StringBuffer, and StringBuilder in Java? (answer)
  • What is String[] args argument in main() method of Java program? (answer)



Just to Add : -

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 )


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 really easy to break by forgetting to intern only a single instance).

salman khandu said...

String s1 = "Hello".concat("World");
String s3 = new String("HelloWorld"); //Line-2
String s2 = s1.intern();
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //false

If I removed Line-2 and compare s1==s2, it will return true. Could anyone explain me what exactly happens in string pool after Line-2?


Javin Paul said...

Hello salman, intern() method put a String into String pool if it doesn't exist and return the reference of same String, but if a similar string exists e.g. which is equal using equals() method then reference of that String is returned from pool.

In first case, because you have "HelloWorld" as literal, it already exists in pool before you call s1.intern() that's why reference of that String is returned and s1 == s2 return false because they both point to different object.

But in second case, "HelloWorld" doesn't exists in pool, hence a call to s1.intern() adds "HelloWorld" and return its reference, in this case both s1 and s2 pointing to same object, hence s1 == s2 is true.

Post a Comment