Java - Spring Boot Memory Management
Java - Spring Boot Memory Management
Java Memory Management – Overview
Java manages memory automatically using Garbage Collection (GC).
JVM divides memory into multiple areas for efficient management.
JVM Memory Areas
Heap Memory
Stores all objects.
Heap is divided into:
Young Generation
Where new objects are created.
Parts:
- Eden Space
- Survivor Space (S0, S1)
Object flow:
Eden → Survivor → Old Generation
GC Type:
- Minor GC (fast)
Old Generation
- Stores
long-living objects - Objects promoted from Young Gen
- Major GC / Full GC happens here (slow)
Stack Memory
Stores:
- Local variables
- Method calls
Features:
- Each thread has its own stack
- Automatically freed
PermGen (Java 7 and below) ❌
Stored:
- Class metadata
- Static variables
- Constant pool
Problems:
- Fixed size
OutOfMemoryError: PermGen
Removed in Java 8
Metaspace (Java 8+)
Replaced PermGen ✅
Stores:
- Class metadata
- Method info
Features:
- Uses native memory
- Auto grows
Config:
-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=256m
Garbage Collectors
Common GCs:
- Serial GC
- Parallel GC
- G1 GC (default)
- ZGC
- Shenandoah
G1 GC (Garbage First)
- Heap divided into
regions - Cleans region with most garbage first
- Low pause time
- Best for large applications
Enable:
-XX:+UseG1GC
JVM Memory Configuration
Heap:
-Xms512m
-Xmx2g
Young Generation:
-Xmn512m
Metaspace:
-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=256m
Enable GC Logging
-Xlog:gc
Common Memory Problems
-
Memory Leak- Objects not released
-
OutOfMemoryError- Heap full
-
High GC- Too many objects
-
Metaspace OOM- Classloader leak
Spring Boot Memory Management
Spring Boot runs on JVM, so JVM memory rules apply plus framework best practices.
Bean Scope Management
-
singleton- Default scope (use carefully)
-
prototype- New instance per request
-
request- Per HTTP request
-
session- Per user session
Avoid storing heavy objects in singleton beans.
Close Resources Properly
Use:
try (InputStream in = ...) {
}
Or:
@PreDestroy
public void cleanup() {
resource.close();
}
Database Connection Pool (HikariCP)
spring.datasource.hikari:
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 300000
max-lifetime: 1800000
Cache Management
Use bounded caches:
Caffeine.newBuilder()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
Avoid:
- Unbounded caches
- Static maps
Thread Management
Do not create threads manually ❌ Use Spring Executor ✅
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor();
exec.setCorePoolSize(5);
exec.setMaxPoolSize(10);
exec.initialize();
return exec;
}
Avoid Large Objects in Session
HttpSession session; // Avoid big objects
File Handling
❌ Load full file in memory ✅ Use streaming
Actuator Monitoring
management.endpoints.web.exposure.include=*
Monitor:
- heap
- GC
- threads
Spring Boot JVM Tuning
-Xms1g
-Xmx4g
-XX:+UseG1GC
-XX:MaxMetaspaceSize=256m
Docker / Kubernetes Memory
Docker:
--memory=2g
Kubernetes:
resources:
limits:
memory: "2Gi"
Debugging Memory Issues
Tools:
- VisualVM
- JProfiler
- JConsole
- Eclipse MAT
Heap dump:
jmap -dump:live,format=b,file=heap.hprof <pid>
Production Best Practices
✔ Bounded caches ✔ Close resources ✔ No static collections ✔ Proper thread pools ✔ GC logging enabled ✔ Monitor heap ✔ Stream large files ✔ Heap dump on OOM
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/dumps
Summary
Java:
- Young Gen → Old Gen
- PermGen ❌ → Metaspace ✅
- G1 GC recommended
Spring Boot:
- Manage beans carefully
- Tune DB pools
- Use bounded caches
- Monitor memory
- Tune JVM
Questions
- Garbage collection? Types of Garbage collections? How do they work?
*Types of GCSerial GC- Single thread
- Small apps
Parallel GC- Multi-threaded
- High throughput
CMS GC- Low pause time
G1 GC- Region-based
- Default (Java 9+)
How GC worksMarkreachable objectsSweepunused objectsCompactmemory
-
what is Region-based GC
Meaning:- Heap is divided into
small fixed regions - instead of Young/Old generations.
- Heap is divided into
- Used in:
G1 GC -
How it works: - Each region can be
young / old / free - GC collects
only required regions - Predictable pause time
Benefit:- Better memory utilization
- Low pause time
Region-based GC =
GC works on small heap regionsinstead of whole heap ✔️ -
what are new improvements in GC after java8
-
G1 GC became default(Java 9) → Region-based → Predictable pause time -
ZGC(Java 11+) → Ultra-low pause (<10ms) → Scalable (TB heap) -
Shenandoah GC→ Low latency → Concurrent compaction -
Epsilon GC→ No GC (testing, performance) -
Better heap management→ Improved compaction → Less fragmentation -
Improved concurrent GC→ Less stop-the-world → Better responsiveness
Post Java8 →
Low latency + scalable + concurrent GCs✔️ -