Optimizing JVM Memory for Spring Cloud Microservices: Practical Tips & Configurations

This guide examines why three simple Spring Cloud microservices consume about 1.5 GB RAM, explains JVM heap and non‑heap memory structures, and provides concrete JVM option settings and container choices to dramatically reduce memory usage while maintaining functionality.

Programmer DD
Programmer DD
Programmer DD
Optimizing JVM Memory for Spring Cloud Microservices: Practical Tips & Configurations

When running Spring Cloud microservices in a non‑production environment, even three minimal services can easily consume around 1.5 GB of RAM, far exceeding the 1 GB–2 GB typically sufficient for a monolithic application.

Observed Memory Usage

Using JProfiler, the memory consumption was visualized, showing that the heap occupies the majority of RAM while the non‑heap also takes a significant portion. The Eureka discovery service uses the least memory.

JVM Memory Layout

The JVM memory is divided into two main areas:

Heap : stores object instances. It consists of Young Generation (Eden, Survivor 0/1) and Old Generation. Minor GC moves surviving objects from Eden to Survivor spaces; Major GC promotes long‑living objects to the Old Generation.

Non‑Heap : stores class metadata, thread stacks, code cache, compressed class space, and direct NIO buffers.

Basic JVM Options for Low‑Memory Services

For a simple Eureka‑based setup without heavy data processing, the following JVM parameters keep the total memory footprint low:

-Xms16m \
-Xmx32m \
-XX:MaxMetaspaceSize=48m \
-XX:CompressedClassSpaceSize=8m \
-Xss256k \
-Xmn8m \
-XX:InitialCodeCacheSize=4m \
-XX:ReservedCodeCacheSize=8m \
-XX:MaxDirectMemorySize=16m

Adjusted Options for REST API Services (Feign/Ribbon)

When the microservice exposes a REST API, slightly larger limits are advisable:

-Xms16m \
-Xmx48m \
-XX:MaxMetaspaceSize=64m \
-XX:CompressedClassSpaceSize=8m \
-Xss256k \
-Xmn8m \
-XX:InitialCodeCacheSize=4m \
-XX:ReservedCodeCacheSize=8m \
-XX:MaxDirectMemorySize=16m

Web Container Comparison

Changing the embedded web container also impacts memory usage. Adding the following dependencies swaps the default Tomcat for Undertow or Jetty:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

Measured memory consumption for the Eureka service alone:

Undertow: 116 MB

Tomcat: 122 MB

Jetty: 128 MB

These results demonstrate that choosing a lightweight container and tuning JVM options can significantly reduce the RAM required by Spring Cloud microservices.

Conclusion

By understanding the distinction between heap and non‑heap memory, applying minimal JVM settings, and selecting an appropriate embedded web server, developers can keep the memory footprint of Spring Cloud microservices well within the limits of a typical development machine, avoiding the unnecessary overhead observed in default configurations.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JVMMemory ManagementMicroservicesBackend Developmentperformance tuningSpring Cloud
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.