Reputation: 5155
I have a Spring boot application once deployed to heroku 512 Mb dyno. At some point the app initialization has started randomly face "Java heap space" error at the point of JPA EntityManager initialization. I have increased the memory to 1 Gb, switching the dyno to Standard-1. The metrics were enabled and I have realized, that for the most time I had 512 Mb and even slightly more occupied.
So, it looks like 1 Gb will be enough, as before it has successfully worked at 512 Mb. And surprisingly, I still get the random success on deployments: for some times I face the Java heap space error and sometimes not. After the success, the memory occupation is of course more than 512 Mb, but significantly less than 1 Gb.
Heroku specifies the -Xmx by itself, I can't configure it.
java $JAVA_OPTS -Xmx256m -jar target/*.jar --spring.profiles.active=prod,heroku,no-liquibase --server.port=$PORT
is a command line to start the app. I can set $JAVA_OPTS to -Xmx900m, but it will not be picked up. Also, it form JAVA_TOOLS_OPTIONS by itsef, setting something about -Xmx671m there for 1Gb Standard-1 heroku dyno. I also can't override this value with my own larger -Xmx
My question is multiple:
1) How I can be sure, that at the Spring-Boot start up JVM already uses -Xmx671m, but not -Xmx256m. Once I have tried to upgrade even to 2 Gb dyno, but even under it I have faced the Java heap space error, like -Xmx256m of the initial command line call that is still the same even for the 2Gb dyno makes sense while -Xmx2Gb set for in in JAVA_TOOLS_OPTIONS is not actually influencing that part of the start up, when the application fails.
2) If the -Xmx from JAVA_TOOLS_OPTIONS actually makes sense, how can Spring Boot application try to occupy more heap at the start up than it use during the work later and how can it occupy the random volume each time? Can be this behavior tuned (say, identify beans that are not used and excluding them; adding some JVM options and so on)
Upvotes: 0
Views: 1426
Reputation: 10318
The best way to confirm the actual Xmx
value is with either the heroku java:jconsole
command or with a command like heroku ps:exec
and then using jinfo
on the process.
You could also include the heroku-javaagent to log memory statistics or use -XX:+PrintGC
. Both of these will log the heap statistics and you can view them with heroku logs --tail
.
I'm not sure I understand the second part of your question, but I suspect you're seeing the JVM use lots of off-heap memory. For more information on why this happens see this blog post on JVM memory categories.
Upvotes: 1