Memory Leaks Due to Improper Bean Scopes in Spring Boot (Production Guide)

Memory leaks in Spring Boot applications are silent killers.

Your application:

  • Starts fine
  • Works fine in dev
  • Passes tests
  • Slowly crashes in production after hours or days

One of the most common hidden causes is improper bean scope usage.

This guide explains:

  • What bean scopes are
  • How wrong scope choices cause memory leaks
  • Real production scenarios
  • How to fix and prevent them permanently

What Is a Memory Leak in Spring Boot?

A memory leak happens when:

  • Objects are no longer needed
  • But still referenced
  • And cannot be garbage collected

Over time:

  • Heap usage keeps growing
  • GC becomes aggressive
  • Application slows down
  • Eventually crashes with OutOfMemoryError

Spring Boot does not automatically protect you from this.

Understanding Bean Scopes in Spring Boot

Every Spring bean has a scope — how long it lives in memory.

Common Spring Boot Bean Scopes

ScopeLifetime
singletonEntire application lifetime
prototypeNew instance per request
requestOne HTTP request
sessionOne user session
applicationServletContext lifetime

Default scope = singleton

Why Improper Bean Scopes Cause Memory Leaks

Spring manages beans — not your object usage logic.

If a bean:

  • Lives longer than it should
  • Holds references to short-lived objects
  • Accumulates state

Then memory leaks are inevitable.

🚨 Most Dangerous Scenario: Stateful Singleton Beans

The Root Problem

Singleton beans live for the entire application lifetime.

If they store:

  • User data
  • Request data
  • Large collections
  • Caches without limits

Memory will never be released.

❌ Bad Example (Very Common in Production)

@Service
public class UserSessionTracker {

private List<UserSession> sessions = new ArrayList<>();

public void track(UserSession session) {
sessions.add(session);
}
}

What goes wrong:

  • Bean is singleton
  • List keeps growing
  • Old sessions never removed
  • Heap keeps increasing

This is a classic memory leak.

✅ Correct Approach

  • Avoid storing state in singleton beans
  • Use request/session scope if needed
  • Or external stores (Redis, DB)

Prototype Beans Injected into Singleton Beans (Hidden Leak)

Why This Is Dangerous

@Component
@Scope("prototype")
public class HeavyObject {}

Injected into:

@Service
public class Processor {

@Autowired
private HeavyObject heavyObject;
}

Problem:

  • Processor is singleton
  • Prototype is created once
  • Never released
  • Defeats prototype purpose

This creates unexpected memory retention.

✅ Correct Solution

Use:

  • ObjectProvider
  • ApplicationContext
  • Factory pattern
@Autowired
private ObjectProvider<HeavyObject> provider;

public void process() {
HeavyObject obj = provider.getObject();
}

Request / Session Scope Used Incorrectly

Common Production Mistake

Using @RequestScope or @SessionScope beans inside singleton services without proxying.

@Service
public class OrderService {

@Autowired
private UserContext userContext;
}

If UserContext is session-scoped:

  • References can leak across sessions
  • Memory grows with user count

✅ Correct Usage

@SessionScope
@Component
public class UserContext {}

And use proxy mode implicitly (Spring Boot handles this correctly when annotated properly).

Caching Inside Beans Without Eviction

Another Silent Memory Leak

@Component
public class CacheService {

private Map<String, Object> cache = new HashMap<>();
}

Issues:

  • No eviction
  • No size limit
  • Runs forever

✅ Fix Using Proper Cache Strategy

Use:

  • Caffeine
  • Redis
  • Spring Cache abstraction

Never build unlimited in-memory caches in singleton beans.

Static Fields Inside Spring Beans

Extremely Dangerous Pattern

@Component
public class MetricsHolder {

public static List<String> logs = new ArrayList<>();
}

Why this leaks:

  • Static lives beyond Spring context
  • Not managed by container
  • Survives reloads
  • Hard to clean

Avoid static state in Spring applications.

Bean Lifecycle & Memory Leaks

Improper cleanup causes leaks.

Missing Cleanup Hooks

Beans that:

  • Open connections
  • Create threads
  • Use executors

Must clean up on shutdown.

✅ Correct Cleanup

@PreDestroy
public void cleanup() {
executor.shutdown();
}

Or implement DisposableBean.

How to Detect Memory Leaks in Production

Symptoms

  • Gradual heap growth
  • Increasing GC time
  • Slow response times
  • Sudden crashes

Tools to Use

  • JVM heap dump
  • VisualVM
  • JConsole
  • Production monitoring (APM)

Best Practices to Prevent Bean Scope Memory Leaks

1. Keep Singleton Beans Stateless

No user data, no request data.

2. Use Proper Scope for State

  • Request data → request
  • User data → session
  • Shared logic → singleton

3. Avoid Manual Object Caching

Let cache frameworks manage memory.

4. Be Careful with Prototype Beans

Never inject prototypes directly into singletons.

5. Clean Resources Properly

Threads, connections, streams must be closed.

Production Checklist (Quick Scan)

✔ Singleton beans have no mutable state
✔ No unbounded collections
✔ No static state
✔ Proper bean scopes used
✔ Cleanup hooks implemented

If any ❌ → memory leak risk.

Internal Links

Insert these exact anchor texts naturally:

FAQs

Can singleton beans cause memory leaks?

Yes, if they hold state or references to short-lived objects.

Does Spring automatically clean unused beans?

No. Spring manages lifecycle, not object usage logic.

Are prototype beans safer than singleton?

Only if used correctly. Misuse can still cause leaks.

Can bean scopes affect performance?

Yes. Wrong scope increases memory usage and GC pressure.

Is memory leak possible without OutOfMemoryError?

Yes. Performance degradation happens long before crashes.

Final Summary

Memory leaks in Spring Boot are rarely obvious.

Most production leaks happen because:

  • Developers misuse bean scopes
  • Stateful logic is placed in singleton beans
  • Cleanup is ignored

Understanding bean scopes is mandatory for production-grade Spring Boot systems.

If you fix this correctly, you prevent:

  • Random crashes
  • Slow degradation
  • Emergency production incidents

Leave a Comment

Your email address will not be published. Required fields are marked *