Question 5 · Section 13

What are the consequences of String immutability?

The problem of excessive allocation in loops leads to:

Language versions: English Russian Ukrainian

Basic Level

Positive consequences

  1. Strings are thread-safe — can be passed between threads without issues
  2. Memory savings — identical strings stored once (String Pool)
  3. Can be used as HashMap keys — hashCode doesn’t change

Negative consequences

  1. Every operation creates a new object — this consumes memory
  2. Concatenation in a loop is a bad idea:
    String s = "";
    for (int i = 0; i < 1000; i++) {
     s += i; // 1000 objects created!
    }
    

The solution — StringBuilder

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i); // One object, in-place modifications
}
String s = sb.toString();

Intermediate Level

Performance impact

The problem of excessive allocation in loops leads to:

  1. Filling of Young Generation (Eden space)
  2. Increased frequency of GC cycles
  3. Memory fragmentation

Rule: for mass modifications, always use:

  • StringBuilder — single-threaded, fast
  • StringBuffer — multi-threaded, slower

Security consequences: working with passwords

A String object with a password will remain in memory until GC decides to collect it. You cannot programmatically “wipe” its contents.

Recommendation: for sensitive data, use char[]:

char[] password = console.readPassword();
// Pattern for console applications (System.console().readPassword()).
// For web applications — other approaches (HTTPS, secure cookie, don't store password).
// ... used it
Arrays.fill(password, (char) 0); // zeroed out

Code design

String immutability encourages a functional style — methods don’t modify arguments but return results. This makes code predictable and easily testable (Pure Functions).


Advanced Level

GC Pressure and optimizations

String immutability creates GC load, but:

  • Short-lived strings are efficiently cleaned up in Minor GC
  • String Deduplication is only available with G1 GC (flag -XX:+UseStringDeduplication). Not supported for ZGC/Shenandoah.
  • Compact Strings (Java 9+) reduce memory consumption by 50% for Latin characters

Security nuances

TOCTOU attack (Time-of-Check to Time-of-Use): impossible with immutable strings, because a string cannot change between the check and the use.

But there’s a flip side:

  • Strings with passwords/tokens remain in heap dumps in plain text
  • Strings can be swapped to disk by the OS
  • String interning makes strings long-lived (Old Gen)

Impact on JIT optimizations

The JIT compiler can aggressively optimize string-related code:

  • Constant folding — computing constant expressions at compile time
  • String intrinsics — native methods for equals(), hashCode(), indexOf()
  • Escape analysis — eliminating unnecessary allocations during concatenation

Summary for Advanced

  • Immutability is “expensive but reliable”: 1000 concatenations = 1000 objects on the heap; StringBuilder = 1 object.
  • The main cost — GC load from careless loop usage
  • For secrets, use char[]/byte[] that can be zeroed out
  • For high-load systems, it’s important to understand the difference between String and StringBuilder
  • When working with secrets, remember the “residual” presence of strings in the heap

Interview Cheat Sheet

Must know:

  • Positive: thread-safety, String Pool, stable HashMap keys
  • Negative: every change = new object, concatenation in a loop creates N objects
  • StringBuilder — the solution for mass modifications (single-threaded, fast)
  • Passwords in String — bad practice: cannot be zeroed, remains in heap dump
  • For secrets use char[] + Arrays.fill(password, (char) 0)
  • String Deduplication — only G1 GC (-XX:+UseStringDeduplication), not ZGC/Shenandoah
  • JIT optimizations: constant folding, string intrinsics, escape analysis

Frequent follow-up questions:

  • Why is concatenation in a loop bad? — 1000 iterations = 1000 objects on the heap → GC pressure
  • Why can’t passwords be stored in String? — Cannot be programmatically wiped, remains in memory until GC
  • What is a TOCTOU attack? — Time-of-Check to Time-of-Use: string changes between check and use; impossible with immutable String
  • When to use StringBuilder vs String? — StringBuilder for loops and mass modifications, String for storage and transfer

Red flags (DO NOT say):

  • “String += in a loop is fine” — for 1000 iterations that’s 1000 objects
  • “Passwords can be stored in String” — they cannot be securely removed from memory
  • “char[] is always safer than String” — char[] can also be in heap dump; but it can be zeroed out
  • “String Deduplication works everywhere” — only G1 GC with the flag

Related topics:

  • [[4. Why is the String class immutable]]
  • [[18. How does String pool work and how is it related to immutability]]
  • [[19. Can you change a String value via reflection]]
  • [[23. How does immutability affect performance]]