How to Debug Java Memory Leaks in GlassFish and Spring Applications: A Complete Developer's Guide
- OrgLance Technologies LLP
- Aug 30, 2025
- 5 min read
Java memory leaks in enterprise applications can severely impact performance and stability. When working with GlassFish application servers and Spring framework applications, understanding how to identify, diagnose, and resolve memory leaks becomes crucial for maintaining healthy production systems. This comprehensive guide walks you through proven techniques and tools to effectively debug memory issues in your Java applications.
Understanding Memory Leaks in Java Applications
Memory leaks in Java occur when objects remain referenced in memory despite no longer being needed by the application. While Java's garbage collector automatically manages memory, certain programming patterns can prevent objects from being collected, leading to gradual memory consumption that eventually causes OutOfMemoryError exceptions.
In GlassFish and Spring applications, memory leaks commonly arise from:
Application-Level Issues:
Unclosed resources (database connections, file streams, network connections)
Static collections that grow indefinitely
Event listeners not being properly removed
Thread-local variables not being cleared
Caching mechanisms without proper expiration policies
Framework-Specific Issues:
Spring bean scopes misconfiguration
Prototype beans not being properly managed
ApplicationContext not being properly closed
Transaction managers holding references to large objects
GlassFish-Specific Issues:
Deployment and redeployment without proper cleanup
ClassLoader leaks during application redeployment
Connection pool misconfigurations
Resource adapter memory retention
Essential Tools for Memory Leak Detection
Heap Dump Analysis Tools
Eclipse Memory Analyzer (MAT) stands out as the most powerful tool for heap dump analysis. It provides detailed object retention graphs, leak suspects reports, and memory usage patterns. MAT can automatically identify potential memory leaks and show you exactly which objects are consuming memory.
VisualVM offers real-time monitoring capabilities and can generate heap dumps on-demand. It's particularly useful for monitoring applications during development and testing phases.
JProfiler provides comprehensive profiling capabilities including memory allocation tracking, garbage collection analysis, and real-time memory monitoring.
JVM Monitoring and Analysis
Java Flight Recorder (JFR) delivers low-overhead profiling with detailed insights into memory allocation patterns, garbage collection events, and application performance metrics.
GlassFish Admin Console includes built-in monitoring capabilities for heap usage, connection pools, and application-specific metrics.
Spring Boot Actuator exposes memory-related endpoints that provide valuable insights into heap usage, garbage collection statistics, and application health metrics.
Step-by-Step Memory Leak Debugging Process
Phase 1: Detection and Initial Analysis
Begin by monitoring your application's memory usage patterns over time. Look for steadily increasing heap usage that doesn't decrease after garbage collection cycles. Key indicators include:
Heap usage continuously growing over time
Frequent OutOfMemoryError exceptions
Degraded application performance
Increased garbage collection frequency and duration
Enable JVM memory monitoring by adding these parameters to your application startup:
bash
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/path/to/dumps
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStampsPhase 2: Heap Dump Generation and Analysis
Generate heap dumps at different points in your application lifecycle to compare memory usage patterns. You can create heap dumps using:
bash
# Using jcmd
jcmd <pid> GC.run_finalization
jcmd <pid> VM.gc
jcmd <pid> GC.dump_heap /path/to/heapdump.hprof
# Using jmap
jmap -dump:live,format=b,file=/path/to/heapdump.hprof <pid>When analyzing heap dumps with Eclipse MAT, focus on:
Leak Suspects Report for automatically identified potential leaks
Dominator Tree to understand object retention relationships
Histogram view to identify objects with unexpected instance counts
Path to GC Roots to understand why objects aren't being collected
Phase 3: Code Analysis and Pattern Identification
Examine your code for common memory leak patterns:
Resource Management Issues: Review all code that opens resources (database connections, file streams, HTTP connections) to ensure proper closure in finally blocks or try-with-resources statements.
Collection Management: Identify static or long-lived collections that might be growing without bounds. Pay special attention to caches, event listener lists, and callback registrations.
Thread Management: Check for thread-local variables that aren't being properly cleaned up, especially in web applications where threads are reused across requests.
GlassFish-Specific Debugging Strategies
Monitoring GlassFish Applications
GlassFish provides comprehensive monitoring capabilities through its admin console. Navigate to the monitoring section to observe:
Heap memory usage trends
Connection pool utilization
Application-specific metrics
Thread pool statistics
Configure GlassFish monitoring by enabling it in the domain configuration:
bash
asadmin enable-monitoring --modules=jvm,connector-connection-pool,web-containerDeployment and Redeployment Issues
One of the most common causes of memory leaks in GlassFish environments involves improper cleanup during application redeployment. When applications are redeployed, the old ClassLoader should be garbage collected, but references from the old deployment can prevent this.
To diagnose ClassLoader leaks:
Monitor the number of loaded classes over multiple deployments
Use heap dumps to identify multiple versions of the same class
Check for static references that might be holding ClassLoader references
Connection Pool Configuration
Improperly configured connection pools can cause memory leaks. Ensure your connection pools have appropriate:
Maximum pool size limits
Connection timeout settings
Idle connection cleanup policies
Statement caching configurations
Spring Framework Memory Leak Debugging
Bean Scope Management
Spring's bean scoping can lead to memory issues when not properly managed. Prototype-scoped beans are particularly problematic because Spring doesn't manage their lifecycle after creation.
Monitor prototype bean usage by:
Tracking bean creation counts through Spring's management interfaces
Using Spring Boot Actuator's beans endpoint to examine bean definitions
Reviewing code that requests prototype beans to ensure proper disposal
ApplicationContext Lifecycle
Ensure proper ApplicationContext shutdown in web applications by registering shutdown hooks or implementing proper ServletContextListener cleanup.
Transaction Management
Long-running transactions or improper transaction boundaries can hold references to large object graphs. Review transaction configurations and ensure transactions are properly committed or rolled back.
Advanced Debugging Techniques
Custom JMX Monitoring
Implement custom MBeans to expose application-specific memory metrics:
java
public interface MemoryMonitorMBean {
long getCacheSize();
void clearCache();
String getMemoryUsageReport();
}Heap Dump Automation
Set up automated heap dump generation based on memory usage thresholds:
bash
-XX:+HeapDumpOnOutOfMemoryError
-XX:+UseGCOverheadLimit
-XX:GCHeapFreeLimit=10Memory Profiling Integration
Integrate memory profiling into your continuous integration pipeline to catch memory issues early in the development cycle.
Prevention Best Practices
Code Review Guidelines
Establish code review practices that specifically check for:
Proper resource disposal in finally blocks or try-with-resources
Appropriate use of weak references for caches
Proper event listener cleanup
Thread-local variable management
Architecture Patterns
Implement architectural patterns that reduce memory leak risks:
Use dependency injection containers properly
Implement proper component lifecycle management
Design stateless components when possible
Use connection pooling appropriately
Testing Strategies
Develop testing strategies that can detect memory leaks:
Load testing with memory monitoring
Deployment/redeployment testing cycles
Long-running stability tests
Memory leak detection in unit tests
Conclusion
Debugging memory leaks in Java applications running on GlassFish with Spring requires a systematic approach combining the right tools, monitoring practices, and code analysis techniques. By following the strategies outlined in this guide, you can effectively identify, diagnose, and resolve memory issues before they impact your production systems.
Remember that prevention is always better than cure. Implementing proper coding practices, regular monitoring, and comprehensive testing will help you avoid memory leaks in the first place. When issues do arise, the combination of heap dump analysis, application monitoring, and systematic debugging will help you quickly identify and resolve the root cause.
Regular monitoring and proactive memory management should be integral parts of your application lifecycle, ensuring optimal performance and stability for your GlassFish and Spring-based applications.





Comments