Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-10855

Out of memory occurred when responding big file data using ShallowEtagHeaderFilter

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Critical
    • Resolution: Invalid
    • Affects Version/s: 3.2.2
    • Fix Version/s: None
    • Component/s: Web
    • Last commented by a User:
      false

      Description

      There is out of memory occured when responding big file data using ShallowEtagHeaderFilter.

      We configured mvc like below.

      <!-- Enables the Spring MVC @Controller programming model -->
      <mvc:annotation-driven/>
      <mvc:default-servlet-handler />

      <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the $

      {webappRoot}

      /resources directory -->
      <!-- mvc:resources mapping="/resources/**" location="/resources/" /-->
      <mvc:resources mapping="/data/**" location="file:$

      {config.uploadDir}

      \" />

      For example, If a client request resource with http://localhost/data/content/a.zip(1GBytes)
      then following stack trace is shown.

      But It's normal when commenting out ETAG filter configuration.

      I also attached spring's web.xml and apache tomcat's web.xml.

      java.lang.OutOfMemoryError: Requested array size exceeds VM limit
      at java.util.Arrays.copyOf(Unknown Source)
      at java.io.ByteArrayOutputStream.grow(Unknown Source)
      at java.io.ByteArrayOutputStream.ensureCapacity(Unknown Source)
      at java.io.ByteArrayOutputStream.write(Unknown Source)
      at org.springframework.web.filter.ShallowEtagHeaderFilter$ShallowEtagResponseWrapper$ResponseServletOutputStream.write(ShallowEtagHeaderFilter.java:245)
      at org.springframework.util.StreamUtils.copy(StreamUtils.java:125)
      at org.springframework.util.FileCopyUtils.copy(FileCopyUtils.java:109)
      at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.writeContent(ResourceHttpRequestHandler.java:244)
      at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:145)
      at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
      at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:73)
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
      at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
      at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
      at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
      at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)

      1. spring-web.xml
        2 kB
        ChangMin Jeon
      2. web.xml
        164 kB
        ChangMin Jeon

        Activity

        Hide
        rstoya05-aop Rossen Stoyanchev added a comment -

        The ShallowEtagHeaderFilter buffers the response in order to calculate the etag in the end and decide whether to write the response out or send a 304. So a memory error is to be expected with such large files. The filter is easy to add but it is not appropriate for all situations.

        Show
        rstoya05-aop Rossen Stoyanchev added a comment - The ShallowEtagHeaderFilter buffers the response in order to calculate the etag in the end and decide whether to write the response out or send a 304. So a memory error is to be expected with such large files. The filter is easy to add but it is not appropriate for all situations.

          People

          • Assignee:
            rstoya05-aop Rossen Stoyanchev
            Reporter:
            jcm1981@gmail.com ChangMin Jeon
            Last updater:
            Rossen Stoyanchev
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              4 years, 9 weeks ago