Skip to main content

Why String is Stored in String Constant Pool

In a previous article Why String is Immutable and Final in Java, I have discussed why String is immutable in nature and advantages and disadvantages String's immutability gives us.

I have also discussed that, all String literals are cached into a special memory area called String Constant Pool and how String's immutability made String constant pool possible.

But the question arises why do Java required a separate constant pool to store Strings, What's the reason, Why strings are not stored in the normal heap memory like other objects do and in this article, I will try to answer these questions.

String Interning

Well, we know String is the most popular type present in Java and almost all Java programs use it. In fact, I have not seen a single Java program which is written without using String.

In general, a normal Java business application deals with thousands of string objects, lots of them have same value associated and lots of them are mid operations string means they are not the final result.

So if we store all those string objects in normal heap memory, lot's of heap will be acquired by just string objects only, and the garbage collector will have to run more frequently which will decrease the performance of the application.

And that's why we have String Constant Pool and String interning process, whenever we create a string literal JVM first sees if that literal is already present in the constant pool or not and if it is there, the new variable will start pointing to the same object, this process is called String Interning.

There are two ways to create a String object
  1. Creating String Literal:: Anything which comes under "" is a string literal e.g. String s1 = "Naresh", by default all string literals interned and goes to SCP.
  1. Creating String object using constructor: If we create a String object using the constructor e.g. String s2 = new String("Naresh"), the object is created in normal heap memory instead of SCP. And that's why creating String object using constructor is not considered a best practice. We can ask s2 to point to SCP instead of normal heap manually by calling intern() method on it i.e. s2.intern().
So in order to save memory consumed by string objects, Java allows more than one reference variable to point to the same object if they have the same value. That's why JVM creators have created a separate memory area SCP for string literals and made a rule that if more than one string variable holding same value than they will point to the same object.

String a = "Naresh";
String b = "Naresh";
String c = "Naresh";

For above code there will be only one object Naresh will be created and all reference variables a, b, c will point to the same object.

In above example string object with value Naresh will get created in SCP only once and all reference a, b, c will point to same object but what if we try to make a change in a e.g. a.replace("a", "").

Ideally, a should have value Nresh but b, c should remain unchanged because as an end user we are making the change in a only. And we know a, b, c all are pointing the same object so if we make a change in a, others should also reflect the change.

string-constant-pool-in-java

But string immutability saves us from this scenario and due to the immutability of string object string object Naresh will never change. So when we make any change in a instead of change in string object Naresh JVM creates a new object assign it to a and then make the change in that object.

So String pool is only possible because of String's immutability and if String would not have been immutable, then caching string objects and reusing them would not have a possibility because any variable would have changed the value and corrupted others.

You can find complete code on this Github Repository and please feel free to provide your valuable feedback.

Comments

Popular posts from this blog

AutoWiring Spring Beans Into Classes Not Managed By Spring Like JPA Entity Listeners

In my previous article JPA Auditing: Persisting Audit Logs Automatically using EntityListeners , I have discussed how we can use Spring Data JPA automate Auditing and automatically create audit logs or history records and update CreatedBy, CreatedDate, LastModifiedBy, LastModifiedDate properties. So in order to save history records for our File entity, we were trying to auto-wire EntityManager inside our FileEntityListener class and we have come to know that we can not do this. We can not inject any Spring-managed bean in the EntityListener because EntityListeners are instantiated by JPA before Spring inject anything into it. EntityListeners are not managed Spring so Spring cannot inject any Spring-managed bean e.g. EntityManager in the EntityListeners. And this case is not just with EntityListeners, you can not auto wire any Spring-managed bean into another class (i.e. utility classes) which is not managed by Spring. Because it is a very common problem and can also arise with other c

Why Single Java Source File Can Not Have More Than One public class

According to Java standards and common practices we should declare every class in its own source file. And even if we declare multiple classes in the single source file (.java) still each class will have its own class file after compilation. But the fact is that we can declare more than one class in a single source file with below constraints, Each source file should contain only one public class and the name of that public class should be similar to the name of the source file. If you are declaring the main method in your source file then main should lie in that public class If there is no public class in the source file then main method can lie in any class and we can give any name to the source file. If you are not following 1st constraint then you will receive a compilation error saying “ The public type A must be defined in its own file ”.  While if you are not following the second constraint you will receive an error “ Error: Could not find or load main class User ” after exec

How Does JVM Handle Method Overloading and Overriding Internally

In my previous article Everything About Method Overloading Vs Method Overriding , I have discussed method overloading and overriding, their rules and differences. In this article, we will see How Does JVM Handle Method Overloading And Overriding Internally, how JVM identifies which method should get called. Let’s take the example of parent class  Mammal and a child  Human classes from our previous blog to understand it more clearly. public class OverridingInternalExample { private static class Mammal { public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); } } private static class Human extends Mammal { @Override public void speak() { System.out.println("Hello"); } // Valid overload of speak public void speak(String language) { if (language.equals("Hindi")) System.out.println("Namaste"); else System.out.println("Hello"); } @