9

I'm running multiple microservices (Spring cloud + docker) in small/medium machines on AWS and recently I found that these machines are often exhausted and need rebooting. I'm investigating the causes of this loss of power, thinking of possible memory leaks or misconfigurations on the instance/container.

I tried to limit the amount of memory these containers can use by doing:

docker run -m 500M --memory-swap 500M -d my-service:latest

At this point my service (standard spring cloud service with one single endpoint that writes stuff to a Redis DB, using spring-data-redis) didn't even start.

Increased the memory to 760M and it worked, but monitoring it with docker I see the minimum is:

CONTAINER           CPU %               MEM USAGE / LIMIT       MEM %               NET I/O             BLOCK I/O             PIDS
cd5f64aa371e        0.18%               606.9 MiB / 762.9 MiB   79.55%              102.4 MB / 99 MB    1.012 MB / 4.153 MB   60

I added some parameters to limit the JVM memory heap but it doesn't seem to reduce it very much:

_JAVA_OPTIONS: "-Xms8m -Xss256k -Xmx512m"

I'm running

  • Spring Cloud Brixton.M5
  • Spring Boot 1.3.2
  • Java 8 (Oracle JVM)
  • Docker
  • Spring data Redis 1.7.1

Is there a reason why such simple service uses so much memory to run? Are there any features I should disable to improve that?

3
  • 2
    +1 I'm also experiencing similar behavior. I'm running a series of Microservices running Spring Cloud, using Brixton.RC1, and running in docker containers (running in docker 1.12 swarm-mode). My containers are using upwards of 800mb of memory. I edited my Dockerfile base image so it uses FROM java:8-jre-alpine instead of the non-alpine JDK base image I was originally using ... but that didn't help much. Anyone have other ideas? Commented Aug 10, 2016 at 19:28
  • I also ran the same container on my RHEL box with docker 1.12 and my personal Mac with Docker for Mac 1.12 beta 21 running on it. The container on the RHEL box was using around 800mb of memory and the one on my mac was using only 350mb of memory. Both containers were started using the same docker run command. Commented Aug 11, 2016 at 12:11
  • +1. Same issue with spring and docker. In my services i use Hibernate, Spring Data REST, Spring Security, jackson etc. And all of them consume over 350mb-500mb and sometimes crash, although they will not be used. I thought microservices should be lightweight. But with this memory usage ... Commented Sep 25, 2016 at 9:56

2 Answers 2

6

We've investigated a number of things in a similar setup in terms of the JVM itself. A quick way to save some memory if using Java 8 is to use the following options:

-Xms256m -Xmx512m -XX:-TieredCompilation -Xss256k -XX:+UseG1GC -XX:+UseStringDeduplication

The G1GC is well documented, the UseStringDeduplication reduces heap usage by de-duplicating the storage of Strings in the heap (we found about 20% in a JSON/XML web service type environment), and the TieredCompilation makes a big difference in the use of CodeCache (from 70Mb down to 10Mb), as well as about 10% less Metaspace at the expense of about 10% startup time.

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

Comments

-2

According to Spring's Installing Spring Boot applications page you can customize the application startup script by either environment variable or configuration file with the JAVA_OPTS variable.

For example: JAVA_OPTS=-Xmx64m

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.