2

I've been reading multiple posts regarding limiting the container's JVM memory, nothing has worked so far, I don't know where I am messing up.

I made a simple "Hello World" in Spring Boot, using a REST controller, it has nothing else.

Such app was exported as a WAR file, running it with the Tomcat JDK 11 image, I can also run it using the JDK image with a FatJar but the problem persists either way.


Expected

Have my Java container not take more than 25 MB memory (for the sake of a number, could be more)

Actual

Such a simple application is taking 200 - 250 MB memory in docker stats


Dockerfile

FROM tomcat:9.0.30-jdk11-corretto
COPY tomcat.war /usr/local/tomcat/webapps/ROOT.war
CMD ["catalina.sh","run"]

docker-compose.yml

version: '3.7'

services:
    hello:
        build:
            context: .
            dockerfile: Dockerfile
        image: app-test
        environment:
            - JVM_OPTS=-Xms13m -Xmx25m
        ports:
            - 8080:8080

I have tried

-Xms13m -Xmx25m

-XX:PermSize=13m -XX:MaxPermSize=25m

Among other flags that I already deleted and forgot about

5
  • 2
    -Xms13m -Xmx25m is only for JVM menory not for the container. Commented Feb 3, 2020 at 3:43
  • @KarthikeyanVaithilingam Oh, does that mean my flags are working but I also have to limit the container in another way? Commented Feb 3, 2020 at 3:45
  • 1
    I really doubt a standard JVM will start with such limited memory (unless you're using some micro edition). Commented Feb 3, 2020 at 4:00
  • @ElliottFrisch It was merely an example, isn't 250MB too much for a simple Hello World? I can't imagine setting up multiple microservices this way Commented Feb 3, 2020 at 4:02
  • 1
    Take a look at GraalVM (hence my non-standard comment). Commented Feb 3, 2020 at 4:19

3 Answers 3

5

To restrict memory for docker containers, you need to add following in your docker-compose.yml file

environment:
  - <name>=<value>
deploy:
  resources:
    memory: 256M

Once you add the above code, then containers would be restricted to given memory limit and you can see the result in docker stats output. For more details about the resource restriction refer this docker documentation.

Note: If the container crosses the given memory limit, the kernel will kill the container.

Sign up to request clarification or add additional context in comments.

2 Comments

That was it, I also changed the image to openjdk 11 slim, it actually made a difference, the Hello World is only taking 90M
@Jouo I'm glad it helped. In docker, choosing base image wisely is important.
2

The environment variable that tomcat's catalina.sh script depends on for java options is : JAVA_OPTS. If you change the compose file to use the following env variable , it should work.

environment: - JAVA_OPTS=-Xmx128m -Xms128m

Apart from the fact that 25m seems a way too less memory for a JVM with tomcat running.

Comments

1

Regardless of how little memory you set for JVM heap (-Xmx) there are lots of other types of non-heap memory that JVM uses: Java using much more memory than heap size (or size correctly Docker memory limit) - you need to take that into account.

You can also avoid setting -Xmx altogether and instead leverage -XX:MaxRAMPercentage: Clarification of meaning new JVM memory parameters InitialRAMPercentage and MinRAMPercentage

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.