0

I have a Spring Boot app which is built to a docker image by mvn spring-boot:build-image. When it runs it prints out a warning:

WARNING: Container memory limit unset. Configuring JVM for 1G container.
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx192915K -XX:MaxMetaspaceSize=343660K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 1G, Thread Count: 250, Loaded Class Count: 58260, Headroom: 0%) 

Now this message seems to appear regardless a machine which it runs on. Whether it's on my local Docker Desktop on Windows or in AWS instance with 2 or 4 GB RAM. I'm not happy with the 200M set for maximum heap size...

Is there a bug in memory calculation or can I tweak it somehow?

UPDATE: I'm using Dockerrun.aws.json v1 in order to deploy to Beanstalk. So I guess I have no control over docker run arguments.

  • Does this answer your question? [How to set Java heap size (Xms/Xmx) inside Docker container?](https://stackoverflow.com/questions/29923531/how-to-set-java-heap-size-xms-xmx-inside-docker-container) – Fullslack Oct 20 '20 at 12:19
  • https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources – rkosegi Oct 20 '20 at 12:34
  • Well, no, it doesn't answer my question. Sorry for confusion. In fact I run the docker image within AWS Elastic Beanstalk. And I have no control over passing any arguments to docker run. Or have I? I'm using Dockerrun.aws.json v1 in order to deploy to Beanstalk. – Tomas Laubr Oct 20 '20 at 20:06

1 Answers1

1

Normally, you'd set a memory limit with docker run -m <size>. The Java buildpack & memory calculator will read this value from the cgroup information then adjust the JVM based on the memory limit you define.

It looks like with Amazon Elastic Beanstalk, you can set a memory limit in your Dockerrun.aws.json. See their container definition format docs.

There are two options:

memory

Amount of memory on the container instance to reserve for the container. Specify a non-zero integer for one or both of the memory or memoryReservation parameters in container definitions.

memoryReservation

The soft limit (in MiB) of memory to reserve for the container. Specify a non-zero integer for one or both of the memory or memoryReservation parameters in container definitions.

I'm not an expert with Amazon Elastic Beanstalk, but from their docs it sounds like you want to set memory.


If one is unable to set the memory limit for some reason your only option at the time of writing is to ignore the warning and use the 1G defaults.

You would then likely want to downsize your environment so that you are not wasting resources. Like if you have a 4G VM, it's only going to configure the JVM to use 1G, so size your VM down to 1G (or something around there) and you'll end up using the available resource better.

Daniel Mikusa
  • 13,716
  • 1
  • 22
  • 28
  • The `memory` parameter applies for `Dockerrun.aws.json v2`. I'm using version 1 of the file (since I have Amzazon Linux 2 and I don't have docker compose). See [info about v1](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/docker.html#docker-no-compose.deploy). Version 1 has a [command](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/single-container-docker-configuration.html#docker-configuration.no-compose) parameter, but I'm not sure how to use in order to solve my problem. – Tomas Laubr Oct 22 '20 at 07:20
  • You may need to check with Amazon and see if that's possible. It doesn't appear to be from their documentation. What I could see in the docs, the v1 of that file doesn't expose the container memory settings (I'm sure someone will correct me if I'm wrong on that point, AWS isn't my area of expertise). If you can't set the container memory limit, then the JBP's memory calculator isn't going to be accurate. You can ignore the warning and just override the memory calculator with the values you want to use. It puts a little more work on you, but you can still use all of the memory. – Daniel Mikusa Oct 22 '20 at 19:38
  • See my update for details on how to override the memory calculator. – Daniel Mikusa Oct 22 '20 at 20:03
  • _the memory calculator is smart enough to see if you've specified one of these and it will not attempt to override it_ - very good point, I didn't know that. Thank you. That would solve my problem. I can set `JAVA_TOOL_OPTIONS` in env. vars. – Tomas Laubr Oct 23 '20 at 06:53
  • BTW, the most obvious question - can I set the container memory limit and avoid the warning `Container memory limit unset.`? :-) – Tomas Laubr Oct 23 '20 at 06:57
  • Unfortunately, I got error message when trying your example: `all memory regions require 1117471K which is greater than 1G available for allocation: -Xmx450M, 0 headroom, -XX:MaxDirectMemorySize=10M, -XX:MaxMetaspaceSize=343671K, -XX:ReservedCodeCacheSize=240M, -Xss228K * 250 threads` – Tomas Laubr Oct 23 '20 at 07:05
  • Ah, crud. Sorry, I missed that validation when I was looking at it earlier. I don't think you can work around that, not unless you can edit `/sys/fs/cgroup/memory/memory.limit_in_bytes` in your container. That is what the memory calculator is reading to determine the container's memory limit. If you can write to that file, which seems unlikely, then you could change what the memory calculator perceives as the container limit. Otherwise, I would suggest opening a feature request and asking for a way to override that: https://github.com/paketo-buildpacks/libjvm/issues. – Daniel Mikusa Oct 23 '20 at 14:48