In Java web development, correctly configuring Tomcat's memory is crucial for performance. Understanding this requires a grasp of JVM fundamentals, memory management, JVM parameters, and Tomcat-specific settings.
JVM memory management
When an application server starts, all referenced classes are loaded into memory via ClassLoader. JVM memory is divided into:
- Heap: stores class instances, arrays (objects created with
new) - Stack: stores local variables (e.g., method parameters)
- Method Area (PermGen/Metaspace): stores constants, static variables, class metadata (methods, fields)
Common OutOfMemoryError types:
-
java.lang.OutOfMemoryError: Java heap space- Heap is full. Not necessarily a bug; might be due to many JARs. Default min heap = 1/64 physical RAM, max = 1/4. Use
-Xms(enitial) and-Xmx(max) to adjust.
- Heap is full. Not necessarily a bug; might be due to many JARs. Default min heap = 1/64 physical RAM, max = 1/4. Use
-
java.lang.OutOfMemoryError: PermGen space- Permanent generatoin (static memory) is full, often due to too many loaded classes. JDK 7 and below use
-XX:PermSizeand-XX:MaxPermSize. JDK 8+ replaced PermGen with Metaspace (shares heap space), so this error no longer occurs.
- Permanent generatoin (static memory) is full, often due to too many loaded classes. JDK 7 and below use
-
java.lang.StackOverflowError- Stack memory exhausted. Usually caused by infinite loops or deep recursion.
Imoprtant JVM parameters
| Parameter | Description |
|---|---|
-server |
Server mode, improves performance on multi-CPU systems (slower startup). Default is client mode. |
-Xms |
Initial heap size (default: 1/64 physical RAM) |
-Xmx |
Maximum heap size (default: 1/4 physical RAM; recommended: half of RAM) |
-XX:PermSize |
Initial permanent generation size (default: 64M; JDK ≤7) |
-XX:MaxPermSize |
Max permanent generation size (default: 64M) |
-XX:SurvivorRatio |
Ratio of Eden to Survivor space (default: 2). Adjust if GC is a bottleneck. |
-XX:NewSize |
Initial young generation size (default: 2M) |
-XX:MaxNewSize |
Max young generation size (default: 32M) |
-Xmn |
Young generation heap size (typically 1/3–1/4 of -Xmx) |
-Xss |
Thread stack size (default ~512K; recommended 128K) |
-verbose:gc |
Log GC details |
-Xloggc:gc.log |
GC log file location |
-XX:+UseParNewGC |
Parallel young generation GC (reduces minor GC pauses) |
-XX:+UseConcMarkSweepGC |
Concurrent mark-sweep GC (reduces major GC pauses; good for large heaps) |
-XX:+UseParallelGC |
Parallel scavenge collector (for multi-core CPUs) |
-XX:ParallelGCThreads |
Number of parallel GC threads |
For heaps > 1GB, consider:
-XX:NewSize=640m -XX:MaxNewSize=640m -XX:SurvivorRatio=16
This allocates 50–60% of heap to young generation, reducing Full GC frequency.
+XX:AggressiveHeap makes -Xms and -Xmx irrelevant; it consumes up to 1GB physical RAM + 1GB swap aggressively.
Configuring Tomcat memory
Edit $TOMCAT_HOME/bin/catalina.sh (Linux) or catalina.bat (Windows).
Linux: Add before cygwin=false:
JAVA_OPTS="-server -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128m"
Windows: Add after @echo off:
set JAVA_OPTS="-server -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128m"
Adjust values based on your hardware and application needs.