ShallowEtagHeaderFilter buffers the response in ResizableByteArrayOutputStream. When it needs to grows the response, it uses ResizableByteArrayOutputStream.resize(int):
ResizableByteArrayOutputStream then creates a new buffer, copies the old buffer into the new buffer, then (implicitly) releases the old buffer.
It would be more efficient to use a linked list of buffers. The resize operation would create a new empty buffer and add it to the linked list of buffers. This approach results in less copying so less overall memory use (reducing the frequently of problems such as
SPR-10855 when due to buffer resizing).
For an example of this approach in use today, see Grails' StreamCharBuffer: https://github.com/grails/grails-core/blob/355a031bfacbdc94c60b4a8fe4131a500c8833cb/grails-encoder/src/main/groovy/org/grails/buffer/StreamCharBuffer.java Note that this approach is also in use in MyFaces, see https://issues.apache.org/jira/browse/MYFACES-3450