by BehindJava

What is a SubString and Memory Leak in Java

Home » java » What is a SubString and Memory Leak in Java

In this tutorial we are going to learn about SubString and Memory Leak in detail.

SubString method is used to get parts of String in Java. It’s defined in String Class and is overloaded one which takes just beginIndex and returns part of String started from beginIndex till end. While other takes two parameter beginIndex and endIndex and returns part of String starting from beginIndex to endIndex-1 and every time you call a SubString()method it will return a new String because String is immutable in Java.

In the case of SubString if beginIndex is equal to length in SubString(int beginIndex) it won’t throw Index OutOfBoundException instead it will return empty String, same is the case when beginIndex and endIndex is same in case of second method. It will only throw StringIndexBoundException when BeginIndex is negative, larger than EndIndex or larger than length of String.

If you look substring method inside String class you will figure out that it calls String (int offset, int count, char value []) constructor to create new String object what is interesting here is value[] which is the same character array used to represent original string. In case If you have still not figured it out, If the Original string is very long and has array of size 1GB no matter how small a Substring is it will be backed up 1GB array. It also stop original string to be garbage collected in case if doesn’t have any live reference.

Avoid substring memory leakage

Though you can not go and change substring method in java you can still make some work around in case you are creating substring of significant longer String. Simple solution is to trim the string and keep the array-size according to substring length. Luckily String has constructor to do this, as shown in below example.

String bj= "behindjava.com substring example"; //a long string
String behindjava= new String(bj.substring(0,9)); //calling String(string) constructor.

If you look code on java.lang.String class you will see that this constructor trim the array if it’s bigger than String itself.

    public String(String original) {
    ...
    if (originalValue.length > size) {
        // The array representing the String is bigger than the new
        // String itself.  Perhaps this constructor is being called
        // in order to trim the baggage, so make a copy of the array.
        int off = original.offset;
        v = Arrays.copyOfRange(originalValue, off, off+size);
    } else {
        // The array representing the String is the same
        // size as the String, so no point in making a copy.
        v = originalValue;
    }
...
}

Another way to solve this problem is to call intern() method on substring, which will than fetch an existing string from pool or add it if necessary.Since the String in the pool is a real string it only take space as much it requires. It’s also worth noting that substrings are not internalized when you call intern method on original method.

package com.behindjava.string;
 
public class SubStringTest {
 public static void main(String[] args) {
  String mainString = "This is a behindjava.com example about substring implemenation";
  System.out.println("Main String size is "+mainString.length());
  String subStringWithMemoryLeak = mainString.substring(10, 15);//Have same memory usage of mainString
  String subStringWithNoMemoryLeak = new String(mainString.substring(10,15));//Have less memory usage of mainString
  String subStringWithNoMemoryLeak2 = mainString.substring(10,115).intern();//Have less memory usage of mainString
}