Reputation: 14898
Reading the source code for String#substring
(Java 1.7) it looks like it reuses the character array, but with different offset and length. This means that if I have an giant String
that I substring, the initial string will never be reclaimed by GC (right?).
What's the easiest way to sure that the giant String
is reclaimed? I am running JavaSE-1.7.
(For the curious, I'll be writing a radix implementation in Java to reduce memory usage. The answer to this question is essential to avoid the radix tree using more memory than necessary)
Upvotes: 1
Views: 398
Reputation: 4256
For pre JDK 7u6 version
You should use String(String)
constructor in that case:
163 public String(String original) {
164 int size = original.count;
165 char[] originalValue = original.value;
166 char[] v;
167 if (originalValue.length > size) {
168 // The array representing the String is bigger than the new
169 // String itself. Perhaps this constructor is being called
170 // in order to trim the baggage, so make a copy of the array.
171 int off = original.offset;
172 v = Arrays.copyOfRange(originalValue, off, off+size);
173 } else {
174 // The array representing the String is the same
175 // size as the String, so no point in making a copy.
176 v = originalValue;
177 }
178 this.offset = 0;
179 this.count = size;
180 this.value = v;
181 }
String s = "some really looooong text";
String s2 = new String(s.substring(0,3));
When you pass result of s.substring()
to String
constructor, it will not use char[]
of the original String
. So the original String
can be GC. This is actually one of the use case when one should use String
constructor. While in most of the cases we should use String
literal assignment.
For JDK 7u6+ version
In Java 7, implementation of String.substring()
has been changed, which now internally uses String(char value[], int offset, int count)
constructor (which we had to use manually in older version to avoid memory leak). This constructor checks it needs original String
's value[]
array or a shorter array would be sufficient. So for JDK 7+ using String.substring()
will not pose memory leak issue. Please have a look at the source code String.substring()
Upvotes: 4
Reputation: 2985
Original String will always be Garbage Collected if required. No one will object. Here is the partial code for substring()
method (JDK 1.7.0_51):
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
So, this method is returning a brand new String object or if beginIndex is 0 then the originam String will be returned. I guess you are concerned about first case. In that case, it has nothing to do with the older one once it is created.
Upvotes: 0