How Much Heap Memory Does Each SpringBoot HTTP Request Really Use?
This article explains how to measure the exact heap memory consumption of individual SpringBoot HTTP and RPC requests by calculating required memory from request size, configuring JVM GC parameters, creating a JMeter test plan, collecting GC logs, and analyzing results to identify optimization opportunities.
Background
In production environments it is often necessary to perform full‑stack load testing, tune GC parameters, and optimise JVM memory allocation. Knowing the heap memory required for a single RPC or HTTP request allows you to calculate the total heap needed for a given concurrency level and to estimate GC frequency.
Experiment Idea
The goal is to determine how much heap memory a single HTTP request consumes in a SpringBoot application and to observe the impact of request size, logging, and GC configuration.
Key Steps
Create a SpringBoot application (version 2.5.4).
Add a POST endpoint ( /create ) to receive an order and a GET endpoint ( /gc ) that triggers System.gc() .
@Slf4j
@RestController
public class TestController {
private AtomicLong count = new AtomicLong(0);
@ResponseBody
@RequestMapping(value = "create", method = RequestMethod.POST)
public String create(@RequestBody Order order) {
//log.warn("Received order cnt{}:{}", count.getAndIncrement(), order);
return "ok";
}
@ResponseBody
@RequestMapping(value = "gc", method = RequestMethod.GET)
public String gc() {
System.gc();
return "ok";
}
}Configure JMeter:
Create a Thread Group with 10 threads, each looping 2000 times (total 20 000 HTTP calls).
Add an HTTP Request Defaults element to set the target URL.
Add an HTTP Header Manager with Content-Type: application/json.
Add an HTTP Request sampler that posts a small JSON payload (≈50 bytes).
Start the SpringBoot application with explicit GC logging and memory settings:
java -server \
-Xmx4g -Xms4g -XX:SurvivorRatio=8 -Xmn2g \
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g -XX:MaxDirectMemorySize=1g \
-XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCCause -XX:+PrintGCDetails \
-XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution \
-XX:+UnlockDiagnosticVMOptions -XX:ParGCCardsPerStrideChunk=32768 \
-XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC -XX:+UseParNewGC \
-XX:ParallelCMSThreads=6 -XX:+CMSClassUnloadingEnabled \
-XX:+UseCMSCompactAtFullCollection -XX:+CMSParallelInitialMarkEnabled \
-XX:+CMSParallelRemarkEnabled -XX:+CMSScavengeBeforeRemark -XX:+PrintHeapAtGC \
-XX:CMSFullGCsBeforeCompaction=1 -XX:CMSInitiatingOccupancyFraction=70 \
-XX:+UseCMSInitiatingOccupancyOnly -XX:+PrintReferenceGC \
-XX:+ParallelRefProcEnabled -XX:ReservedCodeCacheSize=256M \
-Xloggc:/Users/testUser/log/gc.log \
-jar target/activiti-0.0.1-SNAPSHOT.jarBefore the load test, manually trigger a GC to clear warm‑up objects: curl http://localhost:8080/gc Run the JMeter test plan (20 000 HTTP calls). The GC log records the Eden space usage before and after the test.
Result Analysis
After the test the GC log shows that the Eden space used by the 20 000 HTTP calls equals the total heap allocated for those requests. Key observations:
Even with a tiny request body (≈50 characters), each HTTP call allocated about 34 KB of heap.
Increasing the detail field to 1 200 characters raised the per‑request allocation to 36 KB , roughly matching the payload size.
Adding a log statement inside the controller increased the average allocation to 56 KB , indicating that log object creation significantly impacts memory usage.
Removing the detail field dropped the allocation back to 35.7 KB .
These numbers suggest that SpringBoot creates several internal objects per request, and that logging overhead can dominate memory consumption.
Practical Implications
In a real‑world service the per‑request heap usage can be much higher (0.5 MB–1 MB for RPC calls) due to complex business logic, multiple downstream calls, database access, caching, and extensive logging. For a server handling 500 requests per second, this translates to roughly 15 GB of memory allocated per minute, requiring frequent young‑generation GCs.
To keep GC pauses low and improve throughput, it is advisable to:
Limit the size of individual log messages.
Reuse objects where possible.
Tune GC parameters based on measured allocation rates.
Conclusion
The experiment demonstrates that a simple SpringBoot HTTP request can consume around 34 KB of heap, but real applications often exceed this due to additional processing and logging. Accurate measurement and careful tuning are essential for high‑performance backend services.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
