0

I am trying to run my springboot on memory constraint machine of heroku-free. Heroku says you need to keep you -Xmx300m, but we can pass parameter till 512m as that is the upper limit.

The problem is that i am stuck, no matter how minimal i make my app it needs postgrese and redis connection and its using ateleast -Xmx1000m, i even tried some variation with introducing some GC still no luck. Below are the jvm params needed curretly to make my app work,(note:i haven't done any stress testing):

-Xmx1000m -Xms384m -Xss512k -XX:+UseCompressedOops -XX:+UseG1GC

i have even given added server.tomcat.max-threads = 1 in application.properties no luck.

I need to run my app on below jvm params, Any help would be greatly appreciated

-Xmx450m -Xms384m -Xss512k -XX:+UseCompressedOops 

With the above jvm param,app starts but if you make any api hit throws below error UPDATE:

   java.lang.OutOfMemoryError: Java heap space
        at java.io.ByteArrayOutputStream.<init>(ByteArrayOutputStream.java:77) ~[na:1.8.0_131]
        at org.springframework.web.util.ContentCachingRequestWrapper.<init>(ContentCachingRequestWrapper.java:88) ~[spring-web-5.3.8.jar!/:5.3.8]
        at org.springframework.web.filter.AbstractRequestLoggingFilter.doFilterInternal(AbstractRequestLoggingFilter.java:281) ~[spring-web-5.3.8.jar!/:5.3.8]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar!/:5.3.8]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.48.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.48.jar!/:na]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at com.app.x.security.JwtTokenFilter.doFilter(JwtTokenFilter.java:46) ~[classes!/:0.0.1-SNAPSHOT]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-5.3.8.jar!/:5.3.8]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar!/:5.3.8]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.5.1.jar!/:5.5.1]
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.5.1.jar!/:5.5.1]

further i was able to drill down to HeadWritterFilter.class this is part of springSecurity token verification

void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
    Iterator var3 = this.headerWriters.iterator();  //there are 5 values here
while(var3.hasNext()) {
    HeaderWriter writer = (HeaderWriter)var3.next();
    writer.writeHeaders(request, response);             //fails on the last value
}

}

souradeep majumdar
  • 137
  • 1
  • 1
  • 17
  • https://stackoverflow.com/questions/37335/how-to-deal-with-java-lang-outofmemoryerror-java-heap-space-error might help – seenukarthi Aug 17 '21 at 05:53
  • Without knowing why your application is running out of memory, it is very hard to help you. Something could be creating a huge `ByteArrayOutputStream` or it could be something else entirely that’s almost filled up the heap. – Andy Wilkinson Aug 17 '21 at 06:26
  • Please add the full stacktrace. Something is reading a large blob of data in-memory instead of directly streaming it. So I assume this is your own user code that is leading to the issue (reading large chunks of data in-memory instead of directly streaming it to the client. – M. Deinum Aug 17 '21 at 07:25
  • @M.Deinum i have added the stack trace, and the function where its faiing – souradeep majumdar Aug 18 '21 at 06:21
  • @AndyWilkinson i have addded the stack trace and the location where it fails – souradeep majumdar Aug 18 '21 at 06:22
  • The error occurs when caching the request body. Did you include a filter to write the request to the log? Judging by the fact you have a `AbstractRequestLoggingFilter` in there I would say yes. I would suggest removing that from the chain. – M. Deinum Aug 18 '21 at 06:29
  • @M.Deinum you were right, i had followed https://www.baeldung.com/spring-http-logging public class RequestLoggingFilterConfig { public CommonsRequestLoggingFilter logFilter() { CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter(); filter.setIncludeQueryString(true); filter.setIncludePayload(true); filter.setMaxPayloadLength(10000); filter.setIncludeHeaders(false); filter.setAfterMessagePrefix("REQUEST DATA : "); return filter; } } above was the root cause – souradeep majumdar Aug 18 '21 at 07:47

1 Answers1

0

Root cause was logging @M.Deinum you were right, i had followed https://www.baeldung.com/spring-http-logging

public class RequestLoggingFilterConfig {
    public CommonsRequestLoggingFilter logFilter() {
        CommonsRequestLoggingFilter filter
          = new CommonsRequestLoggingFilter();
        filter.setIncludeQueryString(true);
        filter.setIncludePayload(true);
        filter.setMaxPayloadLength(10000);
        filter.setIncludeHeaders(false);
        filter.setAfterMessagePrefix("REQUEST DATA : ");
        return filter;
    }
}
souradeep majumdar
  • 137
  • 1
  • 1
  • 17