Friday, September 21, 2018

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

The String.intern() method can be used to deal with String duplication problem in Java. By carefully using the intern() method you can save a lot of heap memory consumed by duplicate String objects. A String object is said to be 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 the 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 like "abc" then it's automatically stored in String pool, but when you create a new String object e.g. new String("abc"), even though it's the 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 join the Understanding and Solving Java Memory Problems course By Richard Warburton on Pluarlsight to learn more.



Some important things about String.intern() method

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

1) The 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 the main heap space of JVM.

This will help to further reduce String duplication by using String.intern() method.

In the below diagram you can see that s3 and s4 are referring to the same String object "java" in the String pool because they are interned String while s1 and s2 are referring to separate object because they are not interned or not using String literal.

You can also read Java Performance, The Definitive Guide By Scott Oaks to learn more about troubleshooting Java Performance issue caused by String and optimizing the performance of Java applications, or you can join the Understanding and Solving Java Memory Problems course By Richard Warburton on Pluarlsight to learn more.



What is intern() method of String in Java



4) Another thing to know about is that 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. The 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 a ConcurrentMarkSweep garbage collector. You can also check out What's New in Java 8 on Pluralsight to learn more about G1 GC and other changes introduced in Java 8.


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


If you want to learn more about the String class in Java, don't forget to read the 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)
Thanks for reading this article so far. If you like this Java String article, then please share with your friends and colleagues. If you have any questions or feedback then please drop a note. 

7 comments :

SARAL SAXENA said...

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 )

SARAL SAXENA said...

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?

Thanks

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.

Ana said...

In such case, why do i even need intern()? The best way to create a String object is by declaring it this way->

String a="abc";

instead of
String a = new String("abc");

Javin Paul said...

Hello @Ana, if you programatically create string e.g. "abc" + "def" then it won't be created in the pool. In that case, if you want, you can add them into pool by using intern() method.

Unknown said...

if use string.intern() in web frame, how to release the string constant, or the constant pool become very large.

Post a Comment