8229845: Decrease memory consumption of BigInteger.toString()
brian.burkhalter at oracle.com
Mon Aug 19 20:08:24 UTC 2019
Please review a potential fix of .
BigInteger.toString(int radix) for instances with more than 20 ints in the magnitude array works by recursively decomposing the BigInteger into smaller BigIntegers which have no more than 20 ints in their magnitude array and then uses the internal method smallToString() to convert the smaller BigIntegers into Strings. Internally smallToString() uses a StringBuilder to concatenate component digits and then returns the String created by StringBuilder.toString(). The various strings returned by smallToString() are themselves concatenated in another StringBuilder and the value eventually returned by this StringBuilder’s toString() method is the final result. So all in at least four times the memory needed for the character content of the final result is allocated. Also at least the StringBuilder which contains the final result is likely resizing itself to ensure sufficient capacity and performing a copy each time it resizes.
The proposed change  uses one single StringBuilder with capacity sufficient to contain the final result. The memory needed is therefore reduced to twice that needed for the character content of the final result. Also, intermediate StringBuilder self-resizings are eliminated altogether as the StringBuilder has sufficient capacity to contain the final result.
This method is covered in testing by the existing stringConv() method of BigIntegerTest. Numerous other tests were also run with larger values using the same methodology: create a BigInteger x, get the result s = x.toString(radix) for each radix, create a new value BigInteger y = BigInteger(s,radix), verify that y.equals(x) is true.
 https://bugs.openjdk.java.net/browse/JDK-8229845 <https://bugs.openjdk.java.net/browse/JDK-8229845>
More information about the core-libs-dev