Showing posts with label Strings. Show all posts
Showing posts with label Strings. Show all posts

Monday, 25 April 2016

Why String is immutable ?


In Java, Strings are handling in Pool format.

Example


String str1 = “xyz”;
This string(str1) will be stored into memory in particular address. When we defining new String with same array of characters like

String str2 = “xyz”;
Now, JVM will check in String Pool where there is same characters are available or not.

If two Strings are match the JVM will refer str1address to str2. Now the str1 and str2 referring the same characters insame memory location.
This is a good idea for increasing memory efficiency.

When we change the str1 characters, the changes will be reflected to str2, because both str1 and str2 variables are referring the same memory location. For avoiding this we are keeping String as immutable. However we can use StringBuffer if you want to do modifications in the string.

Making String immutable, makes it thread safe and thus improves performance.
Once a string object is created no changes can be made to it. If a string is modified in code a new object will be created.
That is why string is immutable.

What is the memory leak problem with substring() till Java 1.6 ?


In String implementation till JDK 1.6,
  • String is stored as char array
  • Private variables (offset and count) are used to manage the char array

private final char value[];
/** offset = First index of the storage
private final int offset;
/** count = Number of characters in the String
private final int count;
...
...
public String substring(int beginIndex, int endIndex) {
   //check boundary
   return ((beginIndex == 0) && (endIndex == count))? this :
  new String(offset + beginIndex, endIndex - beginIndex, value);
}

String(int offset, int count, char value[]) {
   this.value = value;
   this.offset = offset;
   this.count = count;
}

On calling substring() , it assigns the new values of offset and count variables every time.


Memory leak problem till JDK 1.6

If you have a very long string but only need a small part by using substring() method will return the offset and count which refers the original string array which will not permit to garbage collection of original string array.

This will cause a performance problem, since we need only a small part and keeping the whole char value[] array in memory (No garbage collection).


How programmer can resolve this issue in JDK 1.6 ?

subString = string.substring(3, 10) + "";

In your code, string.substring(3, 10) will return the substring which point to original string array and the substring will not allow the garbage collection for old string (char value[]).

But when we add the empty string to offset, new string will form in constant pool with new char value[] array.
By this way, we can overcome the problem of garbage collection of old string array.




How it has been resolved in JDK 1.7 ?

This problem is fixed by returning the new copy of character array.

public String substring(int beginIndex, int endIndex) {
    // Check boundary
    int subLen = endIndex - beginIndex;
    return new String(value, beginIndex, subLen);

}

public String(char value[], int offset, int count) {
    // Check boundary
    ...
    // It return new copy on array.
    this.value = Arrays.copyOfRange(value, offset, offset + count);
}

Friday, 22 April 2016

How many String objects ?


String s1 = "abc";
// Creates 1 obj in String pool (s1 will refer to object in String pool)

String s2 = new String("xyz");
// Creates 2 new objects, one in String pool and one in heap (s2 will point to object on heap)

s2=s1;
// No new object is created; only assignment will take place

s1.toUpperCase();
// Creates 1 obj

String s3 = "abc";
// No object created (s3 points to existing object in String Pool)

String s4 = s3.replace('a','A');
// Creates 1 new object



Total objects created : 5

String vs. StringBuffer vs. StringBuilder


String is immutable 
whereas StringBuffer and StringBuilder can change their values.

The only difference between StringBuffer and StringBuilder is that StringBuilder is not synchronized whereas StringBuffer is synchronized.
so, when the application needs to be run only in a single thread then it is better to use StringBuilder.
StringBuilder is more efficient than StringBuffer.


Criteria to choose among String, StringBuffer and StringBuilder : 

  • String : If your text is not going to change as String object is immutable.
  • StringBuilder : If your text can change and will only be accessed from a single thread, as StringBuilder is not synchronized.
  • StringBuffer : If your text can change and will be accessed from multiple threads, as StringBuffer is synchronized.