Java string.substring memory leak?

Source: Internet
Author: User

string can be said to be one of the most common Java types, but I've recently heard JDK6 inside String.substring There is a memory leak bug, gang stunned! Let's see what the situation is.

This is the code that can cause the exception in thread "main" Java.lang.OutOfMemoryError:Java Heap space:

public class testgc {    private string largestring =  New string (new byte[100000]);      string getstring ()  {         return this.largestring.substring (0, 2);//In JDK6 will cause out  of memory, there is no problem with JDK7 and 8//        return new  String ("AB");//        return this.largestring.substring (0,2)  +  "";//jdk6 solution, does not appear out of memory//         Return new string (this.largeString.substring (0, 2)),/jdk6 resolution, does not appear out of memory     }     public static void main (String[]  args)  {        java.util.list<string> list =  new java.util.arraylist<string> (;        for ) (int i = 0; i <  100000; i++) &NBSP;{&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;TESTGC &NBSP;GC&NBSP;=&NBSP;NEW&NBSP;TESTGC ();             list.add (Gc.getstring ());        }         system.out.println ("Over"  + list.size ());      }}

But it's safe to run with JDK8. Note that before the online article to see the installation of JDK8, only need to select the compiler option in Eclipse is JDK6, I can not experiment, Think of the string is the JDK inside the Rt.jar class, even if it is compiled to JDK6 code, run time or use the JDK8 string ah, it is not possible to reproduce the bug is normal. To reproduce, you can only download the installation JDK6.

Some people think that this will be out of memory because the TESTGC object has a very large largestring object, but its real call getstring method, TESTGC object can be completely recycled, largestring can also be recycled, The JVM's automatic garbage collection should have no bugs, or else! Instead of changing the GetString method directly to return a string object, you can see that there is no problem.

Now let's see why JDK6 inside, substring can lead to mistakes. Ctrl+b (Idea's view source shortcut key point to see), the code is as follows

Public string substring (Int beginindex, int endindex)  {     if  (beginindex < 0)  {        throw new  stringindexoutofboundsexception (beginindex);    }    if  ( Endindex > count)  {        throw new  Stringindexoutofboundsexception (EndIndex);    }    if  (beginIndex  > endindex)  {        throw new  Stringindexoutofboundsexception (Endindex - beginindex);    }     return  ((beginindex == 0)  &&  (endindex == count))  ?  this :        new string (Offset + beginIndex ,  endindex - beginindex, value);     } 

The first few lines are mainly to do scope check, the most important is

New String (offset + beginindex, endindex-beginindex, value);

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

You can see that the substring in JDK6 the entire value of the original large string, which is the array that holds the actual char in the string.

/** The value is used for character storage. */private final char value[];

And just by modifying beginindex and offset to achieve the reuse of value, to avoid the trouble of array copy (and can improve a bit of performance), but the problem is that if the original string is large, and substring retained for a long time, It is possible to cause the entire large value to not be recycled. The fix for JDK6 is to force the generation of a new string to avoid reusing the value in the original string, such as:

Return this.largeString.substring (0,2) + "";//jdk6, the solution does not appear out of the memory

In fact, this is precisely the JDK8 inside of the implementation of the way. Upper Src:

Public string substring (Int beginindex, int endindex)  {         if  (beginindex < 0)  {             throw new stringindexoutofboundsexception (BeginIndex);         }        if  (endindex  > value.length)  {            throw  new stringindexoutofboundsexception (endIndex);         }         int subLen = endIndex - beginIndex;         if  (sublen < 0)  {             throw new stringindexoutofboundsexception ( Sublen);         }        return  ((beginIndex == 0 )  &&  (endindex == value.length)  ? this                 : new string (value,  Beginindex, sublen);     }

.

Public string (Char value[], int offset, int count)  {         if  (offset < 0)  {             throw new stringindexoutofboundsexception (offset);         }        if  (count <  0)  {            throw new  Stringindexoutofboundsexception (count);        }         // note: offset or count might be near - 1>>>1.        if  (offset > value.length  - count)  {            throw  New stringindexoutofboundsexcEption (Offset + count);        }         this.value = arrays.copyofrange (Value, offset, offset+count);     }

As you can see, the array copy is finally done for value.

In fact, JDK8 modification is also mixed, some people think that JDK6 inside the way to achieve better, more efficient, as long as their attention can avoid the problem, this is the question of the benevolent see, just need to know, JDK6 string of this small pit is good.

Reference articles

    1. http://droidyue.com/blog/2014/12/14/substring-memory-issue-in-java/

    2. http://www.programcreek.com/2013/09/the-substring-method-in-jdk-6-and-jdk-7/


Java string.substring memory leak?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.