2

I'm running a container which includes a J2EE webapp with tomcat docker base image on CoreOS server instance in AWS (t2 medium). Recently I came across on how exceeding memory limits in Docker containers using Java inside would make the containers fail (Resource). After reading the above article I was bit concerned on whether any of containers that I'm running on my CoreOS instance would face this issue in the future.

So I wanted to find out on what would be the default memory limit for a Docker container when no memory limit specified on docker run command, which is the way I'm running my docker containers. As discussed in this forum the answer stated its unlimited and its based on whatever the OS gives it.

But I want to know how CoreOS decides the memory limit for a given container in detail and should I be worried on setting up a memory limit and CPU utilization of a container which is running a webapp with tomcat base image (Will there be any chance that a container exit due to memory overload issue in CoreOS?).

None of the documents I came across on the internet provided a clear answer related to CoreOS or tomcat docker image, for this issue.

Note - I'm managing my Docker containers via systemd.

Ravindu Fernando
  • 3,346
  • 3
  • 16
  • 21

1 Answers1

2

In Docker, by default, a container has no resource constraints. If you do not specify a memory limit for your container, the limit is unlimited. However, it is possible that the memory is limited by your cgroup configuration. In addition, if you are using Kubernetes or another management system, it is possible to define a default limit for a domain or namespace.

Tomcat is a Java Application Server that runs on a virtual machine. The JVM tries to reserve an amount of memory depending on parameters such as the -Xms and -Xmx arguments. In TOMCAT, these parameters may be specified in the catalina.sh startup script or the CATALINA_OPTS and JAVA_OPTS environment variables. If you do not specify a memory limit, Java will use a default one based on the version of the JVM and the available memory. There is a discussion on Java 8 default limits. Java will not use more memory than the specified. If you call other non-Java programs from Tomcat, you must track the memory used by these applications.

  • The Tomcat in the Docker repository does not define a memory limit for the Java runtime. The default tomcat catalina.sh does not define a limit neither.
  • If you use that template, Java (and Tomcat) will use the default values. You may check the values in your system using:

    java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'
    

    In the page you mentioned, they use a CMD in the dockerfile:

    CMD java -XX:+PrintFlagsFinal -XX:+PrintGCDetails $JAVA_OPTIONS -jar java-container.jar
    
  • The page you mentioned used a Fabric8 dockerfile that uses an script to calculate the container restrictions and use the 50% of the available memory as an upper boundary.

  • Determining the amount of memory your application requires is part of the Tomcat tunning. You may find many pages discussing this and another Tomcat parameters such as the number of allowed connections and of threads used in the connectors among others.
  • You may define the memory limit using the -e switch to set environment variables.

    $ docker run -d --name mycontainer -p 8080:8080 -m 800M -e JAVA_OPTIONS='-Xmx300m' ...
    
  • If you define a memory limit for your container, it must be greater than the used by Java. There is an old discussion in the Github issues with some ideas about how much memory to add.


Note that, recent Java versions considers the available memory and CPUs according to the docker/cgroup defined limits. Java systems (including tomcat) may fail at startup if you do not have enough memory or the memory limit is less than the required by the runtime. Linux and Java uses an optimistic mallocand they may fail after a while. You must check all of the cgroups, docker and JVM configurations.

Jaime
  • 2,922
  • 1
  • 14
  • 16