Is it good practice to use java.lang.String.intern?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Java, a versatile and widely-used programming language, offers a rich standard library to developers. One of the functions in this library is java.lang.String.intern(). This method allows developers to store a single instance of a string in a memory pool, theoretically saving memory and improving performance. However, the usage of intern() requires careful consideration, as it may not always yield the anticipated advantages. Let's delve into the inner workings of String.intern(), assessing its benefits, potential pitfalls, and best practices.
Understanding String.intern()
How it Works
In Java, strings are immutable objects, meaning once a string is created, it cannot be altered. The String class in Java maintains a pool of strings, often referred to as the string pool. When a string is interned using intern(), it's stored in the pool. If the pool already contains a string equal to the interned string, the method returns the reference to the existing string instead of storing the new one. Otherwise, it adds the new string to the pool and returns its reference.
Technical Implementation
Here's a demonstration:
As illustrated above, s1 and s2 are not referencing the same object because s1 is a non-pooled instance. Conversely, s2 and s3 are equivalent, as both refer to the interned string in the pool.
Advantages of Using String.intern()
- Memory Reduction: By storing a single instance of each unique string value,
intern()reduces memory usage when there are many duplicates. - Increased Performance: With interned strings, equality checks using
==compare references rather than performing character-by-character comparison, which can be faster in some contexts.
Challenges and Limitations
- Memory Overhead: Interning strings can lead to significant memory consumption in the JVM string pool, particularly when dealing with large numbers of unique strings.
- Performance Bottlenecks: If the applications frequently intern strings, especially in multithreaded environments, it can lead to contention and performance degradation because
intern()involves a lock. - Limited by PermGen/Metaspace: In earlier Java versions, interned strings occupied space in the PermGen, which could lead to
OutOfMemoryError. From Java 8 onwards, interned strings are stored in the heap’s Metaspace, which alleviates some memory pressure but doesn't eliminate it entirely.
When to Use String.intern()
- Use
intern()when dealing with a known set of unique strings where high duplicate frequency is expected. - Avoid using
intern()when handling massive volumes of unique strings, as it could counteract its intended memory-saving benefits by overloading the string pool.
Best Practices
- Profiling: Before opting to intern strings, perform profiling to ascertain whether memory savings will outweigh the potential overhead.
- Selective Interning: Limit its use to only those strings that are confirmed to benefit from interning, ensuring a balance between savings and overhead.
- Update to Java 8+: Whenever possible, run applications on Java 8 or later, where Metaspace offers greater flexibility compared to the deprecated PermGen.
- Thread Management: Carefully manage thread contention if
intern()is used in highly concurrent environments.
Summary Table
| Aspect | Pros | Cons |
| Memory Usage | Reduces duplicate string memory footprint | Larger Metaspace usage for numerous unique strings |
| Performance | Faster == equality checks when strings are interned | Lock contention in concurrent environments |
| Flexibility | Works uniformly across Java versions with variations | Changes in string pool management between versions |
| Use Case Suitability | Best for high-duplicate frequency scenarios | Detrimental for large sets of distinct strings |
In summary, while java.lang.String.intern() provides compelling advantages under certain conditions, it's not a one-size-fits-all solution. Developers should weigh the trade-offs associated with memory and performance, tailoring their use of intern() to suit specific application needs and environments. Proper assessment and selective application can lead to optimized memory usage and improved runtime efficiency.
Related reading
- Is it meaningless to use ReduceLROnPlateau with Adam optimizer?
- Is it meaningless to use ReduceLROnPlateau with Adam optimizer?
- Is it more efficient to copy a vector by reserving and copying, or by creating and swapping?
- Is it necessary to dispose System.Timers.Timer if you use one in your application?
- Is it legal to call the start method twice on the same Thread?
- Is it OK to use a string as a lock object?
- Is it necessary to use autoreleasepool in a Swift program?
- Is it OK to call stdasync at high frequency?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.