I've got an incoming bunch of MultipartFile
objects that I need to send through by embedding them into an XML structure and base64-encoding that structure. Initially the code easily consumed 10-20x that of the size of the files. VisualVM showed that this was due to many copies of the files being present in the form of byte arrays and Strings.
An example cause, consider the following line of code to base64 encode String filesXML
which represents the XML with the files embedded in it :
Base64.encoder().encodeAsString(filesXML.getBytes())
This easily consumes 5x the size of the XML in terms of memory. Because getBytes()
does a copy and the encodeAsString()
method uses a StringBuilder
internally, which apparently easily uses up 4x the size of the byte array it is encoding.
So I adapted code to start working with byte arrays myself and filling them in chunk by chunk, e.g. to construct the XML or to encode it in base64 format. By initializing StringBuffer
or StringBuilder
objects with capacities I know beforehand, I avoid lots of duplication. However I cannot find a way to for example replace things within a String
without causing copying.
Is there a way to work with a String
in-place? Replace parts of it without creating anything new? Create a String based on a byte array without actually copying that array? Etc.