8058779: Faster implementation of String.replace(CharSequence, CharSequence)
Peter Levart
peter.levart at gmail.com
Mon Jun 1 12:09:19 UTC 2015
On 06/01/2015 10:32 AM, Ulf Zibis wrote:
> Hi,
>
> Am 31.05.2015 um 18:03 schrieb Ivan Gerasimov:
>>
>> On 31.05.2015 18:54, Ivan Gerasimov wrote:
>>>
>>> I fixed the code and added the case to the regression test in the
>>> new webrev.
>>>
>> Which is right here:
>> http://cr.openjdk.java.net/~igerasim/8058779/05/webrev/
>
> Shoudn't the user be informed via javadoc about the risk of an
> OutOfMemoryError, just from illegal arguments of this method?
> Example:
> this.value.length() = 100
> target.value.length() = 200
> replacement.value.length() = 50
> results in:
...no replacements made, since target.value.length() >
this.value.length() and 1st indexOf returns -1...
if 1st indexOf returns >= 0, then this.value.length() >=
target.value.length() and the only way to get negative newLenHint is via
an overflow indicating that a String with length() > Integer.MAX_VALUE
would be required to hold the result, which is impossible. We don't have
a special StringTooBigException. OOME is the best approximation here.
IllegalArgumentException is another option, but seems to be to general
in this case. What happens when regexp based replace is fed with such
huge strings?
I had to set the max. heap size to 14Gbytes to get the answer that was
not an OOME caused by not enough heap space:
char[] chars = new char[1 + (1 << 30)];
chars[0] = 'a';
String big = new String(chars);
big.replace("a", big);
Exception in thread "main" java.lang.OutOfMemoryError
at
java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
at
java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at
java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:517)
at java.lang.StringBuilder.append(StringBuilder.java:175)
at java.util.regex.Matcher.appendTail(Matcher.java:1122)
at java.util.regex.Matcher.replaceAll(Matcher.java:1169)
at TestReplace.replace(TestReplace.java:11)
at TestReplace.main(TestReplace.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:502)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Regards, Peter
> newLenHint = -500 --> OutOfMemoryError
> In other words, is this a good reason to throw such an Error?
>
> Little nit:
> Indentation for line continuation should be 8 spaces.
>
> -Ulf
>
More information about the core-libs-dev
mailing list