How to Tune JVM for 1M Daily Logins on an 8 GB Server
This article walks through a step‑by‑step guide for configuring JVM memory, selecting the right garbage collector, and fine‑tuning parameters to reliably handle a platform receiving one million login requests per day on a service node with 8 GB RAM, covering capacity planning, GC choice, heap sizing, thread stack, object aging, and monitoring.
During an Alibaba Cloud technical interview the author was asked how to set JVM parameters for a platform that receives 1 million login requests per day on a service node with 8 GB memory. The article presents a complete interview‑style solution that can be used both as a practical reference and as interview preparation.
Capacity planning for 1 M daily logins
The workload is estimated at 100 login requests per second during peak hours. Assuming three servers, each server processes about 30 requests per second. If each login object has ~20 fields and occupies roughly 500 bytes, the per‑second memory consumption is about 15 KB, which after accounting for RPC, DB, network, and cache can grow to several hundred kilobytes or up to 1 MB.
With a 2 CPU × 4 GB machine (2 GB heap) the Young Generation would fill in a few hundred seconds, triggering a Minor GC. With a 4 CPU × 8 GB machine (4 GB heap) the Minor GC interval extends to several hours, providing a stable baseline for the login service.
Step 1: Capacity planning
Estimate per‑second object allocation and memory usage.
Determine the number of machines and per‑machine heap size.
Balance Young Generation size to control GC frequency.
Step 2: Choosing a garbage collector
Throughput vs. latency
Throughput‑oriented workloads favor larger heaps and fewer GC pauses, while latency‑sensitive services need low pause times. Larger heaps increase GC pause duration, so a trade‑off is required.
GC design considerations
GC must stop the world (STW) during certain phases.
Young Generation uses a copying algorithm; Old Generation uses mark‑sweep.
The goal of any collector is to reduce GC frequency and pause time.
CMS vs. G1
Current mainstream collectors are ParNew+CMS (young + old) or G1. G1 is the officially recommended collector for future use.
Latency‑sensitive services typically use CMS; large‑memory services that require high throughput use G1.
Step 3: Heap and generation sizing
The most critical JVM parameters are the heap size ( -Xms and -Xmx) and the Young Generation size ( -Xmn). A common practice is to set the heap to half of the physical memory. The Young Generation is often set to 3/8 of the heap (Sun’s recommendation) but can be adjusted based on workload: up to 3/4 for stateless web services, or around 1/3 for stateful services.
Thread stack size ( -Xss) defaults to 512 KB–1 MB; with hundreds of threads the total stack memory can become significant.
Step 4: Object aging and promotion
Dynamic age determination moves objects to the Old Generation when the Survivor space exceeds 50 % of its capacity after a Minor GC. Reducing the promotion threshold (e.g., -XX:MaxTenuringThreshold=5) helps keep short‑lived objects in the Young Generation and reduces Full GC frequency.
Step 5–8: Fine‑tuning collector parameters
Typical tuning for a 4 CPU × 8 GB system using ParNew+CMS (latency‑first) includes:
-Xms3072M
-Xmx3072M
-Xmn2048M
-Xss1M
-XX:MetaspaceSize=256M
-XX:MaxMetaspaceSize=256M
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=5
-XX:PretenureSizeThreshold=1M
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+AlwaysPreTouchFor throughput‑oriented workloads on larger machines (8 CPU × 16 GB) the G1 collector is preferred, with parameters such as -XX:+UseG1GC and -XX:MaxGCPauseMillis=150.
Step 9: Monitoring and diagnostics
Enable heap dumps on OOM ( -XX:+HeapDumpOnOutOfMemoryError) and GC logging ( -Xloggc:/path/gc.log, -XX:+PrintGCDetails, -XX:+PrintGCDateStamps) to aid post‑mortem analysis.
Optimization summary
Estimate business load and memory requirements.
Allocate appropriate heap and generation sizes.
Select a GC based on latency vs. throughput needs (CMS for low latency, G1 for high throughput).
Keep short‑lived objects in the Young Generation and limit promotion to the Old Generation.
Perform performance testing before release to validate the configuration.
While JVM tuning can improve performance, most Java applications benefit more from architectural and code optimizations; JVM tuning should be the last resort after those layers have been addressed.
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.
