Java String Pool.

Anton Smirnov
5 min readFeb 25, 2024

--

A Java String pool refers to a collection of strings stored in a specific location known as the Heap. In Java, String is among the most frequently used data types. Unlike primitive types, String is an object, which makes it resource-intensive. For instance, allocating memory for a four-character string requires 56 bytes. Consequently, strings, like other objects, are stored in the heap.

In essence, a String Pool is a collection of strings stored in a specifically designated area within the Heap.

  • The String Pool exists thanks to the immutability of strings in Java and the implementation of string interning.
  • The String Pool aids in conserving memory; however, creating a string may take longer for the same reason.
  • When double quotes are used to create a string (for example, String a = “string”), the program first searches for a string in the pool with the same value. If found, it simply returns a reference to it. Otherwise, a new string is created in the pool, and then a reference to it is returned.
  • When using the new operator, a new String object is created. Subsequently, by utilizing the intern() method, this string can either be placed in the pool or obtain a reference from the pool to another String object with the same value.
  • The String Pool exemplifies the Flyweight pattern.

How do I delete objects from the String Pool in Java?

The topic is not new by any means, yet it remains intriguing for beginners and knowledge seekers alike. It has been a perennially interesting question since ancient times. Additionally, it’s a commonly asked question in technical interviews. Understanding this topic can lead to exploring other fascinating subjects, such as how stacks work in the Java Virtual Machine (JVM), the functioning of the (Garbage Collector, aka GC), the various types of GC, and more.

The String Pool itself does not handle the removal of obsolete or unused objects. This responsibility falls on the Garbage Collector (GC), which is a component of the Java Virtual Machine (JVM).

In Java, the Garbage Collector (GC) is responsible for reclaiming memory occupied by objects that are no longer referenced by any part of the program. When an object becomes inaccessible, meaning there are no references to it, it becomes a potential candidate for garbage collection.

When the Garbage Collector (GC) initiates, it examines the object graph starting from root objects, such as static variables, stack local variables, and active threads. During the traversal of the graph, inaccessible objects are identified. Any object, including strings, that cannot be reached from the root objects is considered obsolete or unused.

The Garbage Collector (GC) employs various algorithms to identify objects that are no longer in use. One widely used algorithm is the mark-and-sweep algorithm, also known as marking and sweeping. This approach involves marking accessible objects and then scanning the memory. During traversal, memory occupied by unmarked (inaccessible) objects is reclaimed and released.

If a string object in the String Pool becomes unreachable (due to going out of scope or having all references to it deleted), it becomes a candidate for garbage collection (GC) processing. During the garbage collection process, obsolete string objects are identified, and their memory is freed up for reuse.

It’s crucial to remember that GC is an automatic process that operates in the background. The cleanup cycle and strategies employed by the GC may differ depending on the JVM implementations and versions.

Ultimately, the Java Virtual Machine is tasked with overseeing both the management of the String Pool and the GC. This ensures efficient memory utilization and the automatic recovery of obsolete objects.

Why is using char[] preferred over String for storing a password in Java?

  • Safety. In Java, objects of the String data type are immutable, meaning their contents cannot be altered after creation, and they are stored in memory in their original form. Even after deletion or masking of a password, its actual value persists in memory. This poses a security risk as an attacker could potentially retrieve the password value from a Heap Dump. However, with an array of characters, simply clearing its contents is sufficient to conceal the actual value.
  • Simplicity. When using an array (char[]), we can explicitly erase the data once we have finished working with it. Furthermore, we can freely rewrite the array as needed, ensuring that no valid password remains in the system, even before garbage collection (simply changing a few cells to invalid values is sufficient). Meanwhile, a String is an immutable class. In other words, attempting to alter its value results in a new String being created, while the previous one remains in the string pool. Deleting the String value of a password can be challenging, as it requires the garbage collector to precisely remove the value from the String pool, and there’s a high likelihood that this String value will persist there for a significant duration. Therefore, in terms of data storage security, a char array surpasses a String in this scenario.

Employing an array of characters may prove simpler than utilizing a String data type object for certain tasks, such as encryption and decryption of passwords. This is primarily because many libraries are tailored to work with arrays composed of characters or bytes:

Here’s a straightforward example of storing a password in a char[] array in Java:

char[] password = {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};

Once the password is no longer required for further use, its actual value can be erased from memory:

Arrays.fill(password, '0');

This will fill the array with null characters, effectively erasing all its contents.

  • Output. If the String value is inadvertently printed to the console or logs, its actual value will be exposed:
String password = "password";
System.out.println("Password is : " + password);

Console output:

Password is : password

Similarly, if an array is mistakenly printed to the console:

char[] arr = new char[]{'p','a','s','s','w','o','r','d'};
System.out.println("Password is : " + arr);

the console will display:

Password is : [C@7f31245a
  • Cryptography. The official documentation, the Java Cryptography Architecture Guide, explicitly recommends storing passwords in char[] instead of String: It might seem logical to collect and store passwords in an object like java.lang.String. However, there’s a caveat: String objects are immutable, meaning there are no methods defined to change (overwrite) or clear the contents of a String object after use. This characteristic makes String objects unsuitable for storing sensitive information like user passwords. Instead, it’s advisable to always collect and store sensitive security information in a char array.

Conclusion.

In this article, I explain the String Pool, how to delete objects from the String Pool, the role of the JVM in Java, and how the Java compiler optimizes memory allocations for String objects through the Java String Pool.

https://test-engineer.online/

--

--

Anton Smirnov
Anton Smirnov

Written by Anton Smirnov

I’m a software engineer who specializes in testing and automation. My top languages are Java and Swift. My blog is https://test-engineer.tech/

No responses yet