From 6de0be16c2090164859b4199c2a3fcac82bdda50 Mon Sep 17 00:00:00 2001 From: Ryan Rupp <3022260+ryanrupp@users.noreply.github.com> Date: Thu, 5 Jan 2023 14:44:05 -0600 Subject: [PATCH] Optimize initial buffer size in ContentCachingRequestWrapper Prior to this commit, the initial buffer size for content caching allocated in `ContentCachingRequestWrapper` would be: * the request content length, if available in request headers * the cache limit size as configured on the wrapper The latter is really an upper bound and should not be considered as a good default in most cases. This commit ensures that the request content length is still used if available, but uses a default 1024 size if it's not. While this change will probably cause more reallocations as the buffer grows, this will avoid large allocations in many cases and should overall help with GC. Closes gh-29775 --- .../web/util/ContentCachingRequestWrapper.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java index 8ce2739c88..e63f7fd866 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingRequestWrapper.java @@ -56,6 +56,8 @@ import org.springframework.lang.Nullable; */ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { + private static final int DEFAULT_BUFFER_SIZE = 1024; + private final ByteArrayOutputStream cachedContent; @Nullable @@ -75,7 +77,8 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { public ContentCachingRequestWrapper(HttpServletRequest request) { super(request); int contentLength = request.getContentLength(); - this.cachedContent = new ByteArrayOutputStream(contentLength >= 0 ? contentLength : 1024); + this.cachedContent = new ByteArrayOutputStream(contentLength >= 0 ? + contentLength : DEFAULT_BUFFER_SIZE); this.contentCacheLimit = null; } @@ -88,7 +91,9 @@ public class ContentCachingRequestWrapper extends HttpServletRequestWrapper { */ public ContentCachingRequestWrapper(HttpServletRequest request, int contentCacheLimit) { super(request); - this.cachedContent = new ByteArrayOutputStream(contentCacheLimit); + int contentLength = request.getContentLength(); + int initialBufferSize = contentLength >= 0 ? contentLength : DEFAULT_BUFFER_SIZE; + this.cachedContent = new ByteArrayOutputStream(Math.min(initialBufferSize, contentCacheLimit)); this.contentCacheLimit = contentCacheLimit; }