Backend Development 25 min read

How to Set JVM Parameters for a Platform Handling 1 Million Daily Logins on an 8 GB Server

This article explains how to estimate capacity, choose appropriate garbage collectors, and configure JVM memory settings—including heap size, young generation, thread stack, and GC options—for a service that processes one million login requests per day on a node with 8 GB of RAM, providing step‑by‑step guidance and example command lines.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
How to Set JVM Parameters for a Platform Handling 1 Million Daily Logins on an 8 GB Server

The author revisits a technical interview question about configuring JVM parameters for a platform that receives 1 M login requests daily on a service node with 8 GB memory, offering both practical tuning steps and interview preparation insights.

Step 1: Capacity Planning for a New System

Estimate object creation rate per second, calculate required young generation size, and determine the number of machines needed to keep Minor GC frequency low. Example: with three 4C8G servers, allocating a 4 GB heap (2 GB young generation) can handle the load.

Step 2: Choosing a Garbage Collector

Throughput vs. Latency

Throughput‑oriented configurations favor larger heaps (fewer GC pauses but longer pause times), while latency‑oriented setups use smaller heaps to reduce pause duration. The trade‑off must be evaluated based on service requirements.

GC Design Considerations

GC must not allocate new objects while collecting.

Stop‑The‑World (STW) pauses halt request processing.

Young generation uses copying algorithms; old generation prefers non‑copying to save space.

The goal of any collector is to reduce GC frequency and pause time.

CMS vs. G1

ParNew+CMS is common for low‑latency services, while G1 is the recommended default for newer JVMs and larger heaps.

Step 3: Partition Size Planning

Set -Xms and -Xmx to about half of physical memory (e.g., 4 GB for an 8 GB node). Choose -Xmn (young generation) based on workload: stateless web services may use up to 75 % of the heap, while stateful services often keep it around 33 %.

Configure thread stack size with -Xss (typically 512 KB–1 MB).

JVM Parameter

Description

Default

Recommended

-Xms

Initial heap size

OS memory /64

~50 % of RAM

-Xmx

Maximum heap size

OS memory /4

~50 % of RAM

-Xmn

Young generation size

~1/3 of heap

3/8 of heap (Sun default) or adjust per workload

-Xss

Thread stack size

Depends on JDK/OS

512 KB–1 MB

Step 4: Tuning Survivor and Tenuring

Use -XX:SurvivorRatio=8 to set Eden:Survivor = 8:1:1 (e.g., 1.6 GB Eden, 0.2 GB each Survivor). Adjust -XX:MaxTenuringThreshold (e.g., 5) so objects survive only a few Minor GCs before promotion.

Step 5: Direct Allocation of Large Objects

Set -XX:PretenureSizeThreshold=1M to allocate objects larger than 1 MB directly in the old generation.

Step 6: CMS Old‑Generation Optimisation

For JDK 8, the default collector is Parallel GC; for heaps larger than 4 GB, G1 is preferred. For low‑latency services, use ParNew+CMS with options such as -XX:CMSInitiatingOccupancyFraction=70 and -XX:+UseCMSInitiatingOccupancyOnly .

Step 7: OOM and GC Logging

Enable heap dumps on OOM with -XX:+HeapDumpOnOutOfMemoryError and specify a path. Add GC logging flags like -Xloggc:/path/gc.log , -XX:+PrintGCDetails , and -XX:+PrintGCDateStamps for troubleshooting.

Step 8: General JVM Parameter Templates

Example template for a 4C8G machine (response‑oriented):

-Xms4g
-Xmx4g
-Xmn2g
-Xss1m
-XX:SurvivorRatio=8
-XX:MaxTenuringThreshold=10
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+AlwaysPreTouch
-XX:+HeapDumpOnOutOfMemoryError
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:gc.log

For throughput‑oriented workloads, a G1 template (8C16G) is recommended:

-Xms8g
-Xmx8g
-Xss1m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=150
-XX:InitiatingHeapOccupancyPercent=40
-XX:+HeapDumpOnOutOfMemoryError
-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:gc.log

Additional Topics

What is ZGC?

ZGC is a low‑latency collector introduced in JDK 11, targeting pause times under 10 ms for heaps up to several terabytes.

How to Choose a Collector

Small heap or single‑core: -XX:+UseSerialGC

Throughput‑oriented: -XX:+UseParallelGC

Low‑latency: -XX:+UseConcMarkSweepGC , -XX:+UseG1GC , or -XX:+UseZGC

Metaspace vs. Permanent Generation

Java 8 replaced the fixed‑size PermGen with native‑memory‑backed Metaspace, eliminating the OutOfMemoryError: PermGen space issue and allowing the size to grow with available system memory.

Stop‑The‑World, OopMap, and Safepoints

GC pauses require all Java threads to stop at safepoints, where the JVM knows the locations of object references via OopMaps.

Overall, the article provides a comprehensive step‑by‑step guide to capacity estimation, GC selection, memory partitioning, and JVM flag tuning for high‑traffic login services.

BackendJavaJVMperformanceMemory ManagementGC tuning
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

login 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.