Course contents

Interning and compact strings

Exact String.intern() semantics and costs, when interning helps or hurts, G1 string deduplication, compact strings (JEP 254) with LATIN1 and UTF16 coders, and measuring string memory with JOL and heap dumps.

PremiumOften askedLesson15 min readSeniorReviewed Oct 2026 · Java 21
On this page
  1. Picture it first: a library catalogue and a photocopier
  2. Compact strings under the hood (JEP 254)
  3. intern(): exact semantics and what it costs
  4. Real world: string deduplication and measuring the heap
  5. Advanced: choosing between the three levers
  6. How to say it in the interview

🗜️ What are interning and compact strings?

Interning means keeping one canonical String per distinct text: s.intern() returns the pooled instance equal to s, so a million rows that all say "MUMBAI" can share one object instead of holding a million copies. Compact strings (Java 9, JEP 254) is the JVM storing a string's text as one byte per character when every character fits in Latin-1, instead of two. Together with GC string deduplication, they're the three levers the JVM gives you for the single biggest consumer of most Java heaps: text.

For this lesson, we'll focus on the exact semantics of intern() and what it costs, when interning saves memory and when it quietly hurts, how G1's -XX:+UseStringDeduplication differs from interning, how compact strings change the layout of every String, and how to measure all of this with JOL and a heap dump. This topic comes up in senior and performance-focused rounds, usually as "your service uses 6 GB of heap and half of it is strings, what do you do?".

Below the line (out of scope)

The 30-second answer

s.intern() looks the text up in the JVM's StringTable; if an equal string is pooled it returns that one, otherwise (since Java 7) it registers s itself and returns it. It's useful for long-lived, low-cardinality values parsed at runtime, but it's a native call costing tens of nanoseconds through a global table, so for high-cardinality data or hot paths it hurts; a private HashMap deduper or an enum is usually better. G1 string deduplication (-XX:+UseStringDeduplication) is the automatic alternative: the GC makes equal long-lived strings share one byte[], but the String objects and their identities stay separate. Compact strings (Java 9, on by default) store text in a byte[] with a coder: LATIN1 uses one byte per char, UTF16 two, which cuts the size of typical ASCII-heavy strings by roughly a third to a half. You verify all of it with JOL or a heap dump, not by guessing.

What you’ll learn

  • State what intern() returns in both cases and why intern() == original depends on what already ran
  • Explain the costs of interning (native call, global table, ~70 ns) and pick better tools: enums and private dedupers
  • Describe how G1 string deduplication shares byte[] arrays without changing identity, and how to enable it
  • Explain compact strings (JEP 254): byte[] value + coder, LATIN1 vs UTF16, and the real byte savings
  • Measure string memory with JOL, jcmd GC.class_histogram and a heap dump before changing anything

Interview radar

Asked very often: "What does intern() do and when would you use it?" and "What are compact strings?" Senior rounds probe: Why intern() can make things slower, how string deduplication differs from interning, and why one emoji doubles a string's size. Production angle: A heap dump showing millions of identical Strings (status codes, city names, JSON keys) after loading a large dataset into memory.

01Picture it first: a library catalogue and a photocopier

Imagine a warehouse that stores a printed label on every one of 5 million parcels. Most labels say one of 40 city names. Three ways to save paper:

  • Interning is a clerk who, every time a label is printed, checks a central catalogue and says "we already have a 'MUMBAI' label, staple a pointer to that one instead". It works, but every parcel waits for the clerk.
  • Deduplication is a night-shift worker who walks the shelves while nobody's looking, finds parcels with identical labels and makes them all point to one sheet. Daytime work isn't slowed, but the parcels themselves (the String objects) are still there.
  • Compact strings is printing labels in a smaller font whenever the text is plain English letters, and the big font only when a label contains a symbol like ₹.

Let's start with the font, because it applies to every string in every Java 9+ program. The picture below compares the same text before and after JEP 254.

Fig. 1

On Java 8 "hello" costs 56 bytes because each char takes two bytes; with compact strings the LATIN1 form costs 48 bytes; a single non-Latin-1 character like the rupee sign switches the whole string to two bytes per char

On Java 8 "hello" costs 56 bytes because each char takes two bytes; with compact strings the LATIN1 form costs 48 bytes; a single non-Latin-1 character like the rupee sign switches the whole string to two bytes per char

02Compact strings under the hood (JEP 254)

Try it yourself first

Before reading on, guess the total footprint (the String plus its array) of "hello", "héllo wörld 2026 ok" (19 chars) and "₹ payment" (9 chars) on JDK 21.

Here's how I measure it with JOL, the Java Object Layout tool from OpenJDK:

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.info.GraphLayout;

public class StringFootprint {
    public static void main(String[] args) {
        System.out.println(ClassLayout.parseClass(String.class).toPrintable());
        for (String s : new String[] {"hello", "héllo wörld 2026 ok", "₹ payment"}) {
            System.out.println(s + " -> " + GraphLayout.parseInstance(s).totalSize() + " bytes");
        }
    }
}

Premium lesson

Keep reading with the Java Pass

The rest of this lesson is part of Java One-Stop Interview Prep: in-depth explanations, diagrams, model answers and how to say them in the interview.

  • intern(): exact semantics and what it costs
  • Real world: string deduplication and measuring the heap
  • Advanced: choosing between the three levers
  • How to say it in the interview

From ₹199 · one-time payment · No auto-renewal

Practise this topicStrings in depth: interview questions & scenarios
Further reading (9)