Lesson Completion
Back to course

Module 18: Memory Management

Overview

This module provides comprehensive coverage of Java memory management, including JVM architecture, memory areas, garbage collection, memory leaks, and performance tuning techniques.

Learning Objectives

  • Understand JVM memory architecture
  • Learn about different memory areas
  • Master garbage collection concepts
  • Identify and prevent memory leaks
  • Perform memory profiling and analysis
  • Optimize memory usage
  • Understand weak, soft, and phantom references

Topics Covered

18.1 JVM Architecture

18.1.1 JVM Components

  • Class Loader Subsystem
  • Runtime Data Areas
  • Execution Engine
  • Native Method Interface
  • Native Method Libraries

18.1.2 Class Loader Subsystem

  • Bootstrap Class Loader
  • Extension Class Loader
  • Application Class Loader
  • Loading, Linking, Initialization
  • Custom Class Loaders

18.1.3 Execution Engine

  • Interpreter
  • JIT (Just-In-Time) Compiler
  • Garbage Collector
  • Profiler

18.2 JVM Memory Structure

18.2.1 Runtime Data Areas

  • Heap Memory
  • Stack Memory
  • Method Area
  • PC Registers
  • Native Method Stack

18.2.2 Heap Memory

  • Young Generation
    • Eden Space
    • Survivor Spaces (S0, S1)
  • Old Generation (Tenured)
  • Object Storage
  • Garbage Collection Target

18.2.3 Stack Memory

  • Thread-Specific
  • Method Frames
  • Local Variables
  • Method Call Stack
  • Stack Overflow

18.2.4 Method Area (Metaspace)

  • Class Metadata
  • Static Variables
  • Constant Pool
  • Method Data
  • PermGen (Old) vs Metaspace (Java 8+)

18.2.5 PC Register

  • Program Counter
  • Thread-Specific
  • Next Instruction

18.2.6 Native Method Stack

  • Native Method Calls
  • JNI Operations
  • C/C++ Integration

18.3 Object Creation and Memory Allocation

18.3.1 Object Creation Process

  • Class Loading
  • Memory Allocation
  • Initialization
  • Reference Assignment

18.3.2 Memory Allocation

  • Eden Space Allocation
  • TLAB (Thread-Local Allocation Buffer)
  • Fast Path Allocation
  • Slow Path Allocation

18.3.3 Object Memory Layout

  • Object Header
    • Mark Word
    • Class Pointer
  • Instance Data
  • Padding
  • Memory Alignment

18.3.4 String Pool

  • String Interning
  • String Constant Pool
  • Memory Optimization
  • intern() Method

18.4 Garbage Collection

18.4.1 Introduction to GC

  • Automatic Memory Management
  • Mark and Sweep
  • Generational Hypothesis
  • GC Roots
  • Reachability

18.4.2 GC Roots

  • Local Variables
  • Static Variables
  • Active Threads
  • JNI References
  • Reachability Analysis

18.4.3 Generational GC

  • Young Generation Collection
  • Old Generation Collection
  • Minor GC
  • Major GC
  • Full GC

18.4.4 GC Algorithms

  • Mark-Sweep
  • Mark-Sweep-Compact
  • Mark-Copy
  • Reference Counting (Not Used in Java)

18.4.5 Young Generation GC

  • Eden and Survivor Spaces
  • Copy Algorithm
  • Age Threshold
  • Promotion to Old Gen

18.4.6 Old Generation GC

  • Mark-Sweep-Compact
  • Longer Pauses
  • Less Frequent
  • Full Collection

18.5 Garbage Collectors

18.5.1 Serial GC

  • Single-Threaded
  • Stop-The-World
  • Small Applications
  • -XX:+UseSerialGC

18.5.2 Parallel GC (Throughput Collector)

  • Multi-Threaded
  • Stop-The-World
  • High Throughput
  • -XX:+UseParallelGC

18.5.3 CMS (Concurrent Mark Sweep)

  • Low Latency
  • Concurrent Phases
  • Fragmentation Issues
  • Deprecated in Java 9

18.5.4 G1 GC (Garbage First)

  • Default since Java 9
  • Region-Based
  • Predictable Pauses
  • Large Heaps
  • -XX:+UseG1GC

18.5.5 ZGC (Z Garbage Collector)

  • Ultra-Low Latency
  • Concurrent GC
  • Scalable
  • Java 11+
  • -XX:+UseZGC

18.5.6 Shenandoah GC

  • Low Pause Times
  • Concurrent Compaction
  • Java 12+
  • -XX:+UseShenandoahGC

18.5.7 Epsilon GC

  • No-Op Collector
  • Testing/Benchmarking
  • Short-Lived Apps
  • -XX:+UseEpsilonGC

18.6 GC Tuning

18.6.1 JVM Memory Options

  • -Xms (Initial Heap)
  • -Xmx (Maximum Heap)
  • -Xmn (Young Generation)
  • -XX:NewRatio
  • -XX:SurvivorRatio

18.6.2 GC Logging

  • -Xlog:gc (Java 9+)
  • GC Log Analysis
  • Pause Times
  • Throughput Metrics

18.6.3 Tuning Goals

  • Throughput
  • Latency
  • Footprint
  • Trade-offs

18.6.4 Common GC Parameters

  • -XX:MaxGCPauseMillis
  • -XX:GCTimeRatio
  • -XX:ParallelGCThreads
  • -XX:ConcGCThreads

18.7 Memory Leaks

18.7.1 Understanding Memory Leaks

  • Unintentional Object Retention
  • Growing Memory Usage
  • OutOfMemoryError
  • Performance Degradation

18.7.2 Common Causes

  • Static Collections
  • Listeners Not Removed
  • Unclosed Resources
  • ThreadLocal Variables
  • Inner Class References
  • Caching Issues

18.7.3 Detecting Memory Leaks

  • Heap Dumps
  • Memory Profilers
  • GC Logs
  • Monitoring Tools

18.7.4 Prevention Strategies

  • Proper Resource Management
  • WeakHashMap Usage
  • Listener Cleanup
  • ThreadLocal Cleanup
  • Bounded Caches

18.8 Reference Types

18.8.1 Strong References

  • Default Reference Type
  • GC Behavior
  • Object Retention
  • Normal Variables

18.8.2 Soft References

  • SoftReference
  • Memory-Sensitive Caches
  • GC Behavior
  • Before OutOfMemoryError

18.8.3 Weak References

  • WeakReference
  • WeakHashMap
  • GC Behavior
  • Next GC Cycle

18.8.4 Phantom References

  • PhantomReference
  • Finalization Alternative
  • Reference Queue
  • Cleanup Actions

18.8.5 Reference Queues

  • ReferenceQueue
  • Notification Mechanism
  • Cleanup Tasks
  • Polling/Blocking

18.9 Finalization

18.9.1 finalize() Method

  • Object Cleanup
  • Before GC
  • Deprecated (Java 9+)
  • Problems

18.9.2 Finalization Issues

  • Unpredictable Timing
  • Performance Impact
  • Resurrection
  • Better Alternatives

18.9.3 Alternatives to finalize()

  • try-with-resources
  • Cleaner API (Java 9+)
  • Explicit Cleanup Methods
  • PhantomReference

18.10 Cleaner API (Java 9+)

18.10.1 Understanding Cleaner

  • Finalization Alternative
  • Explicit Registration
  • Cleaner Thread
  • Resource Management

18.10.2 Using Cleaner

  • Cleaner.create()
  • register() Method
  • Cleanable Interface
  • Best Practices

18.11 Memory Profiling

18.11.1 Profiling Tools

  • JVisualVM
  • JConsole
  • Java Mission Control
  • YourKit
  • JProfiler
  • Eclipse MAT

18.11.2 Heap Dumps

  • Creating Heap Dumps
  • -XX:+HeapDumpOnOutOfMemoryError
  • jmap Command
  • Analyzing Dumps

18.11.3 Memory Analysis

  • Object Retention
  • Dominator Tree
  • Shallow vs Retained Size
  • Leak Suspects

18.11.4 Thread Dumps

  • Thread States
  • Stack Traces
  • Deadlock Detection
  • jstack Command

18.12 Memory Optimization

18.12.1 Object Pooling

  • Reusing Objects
  • Pool Implementation
  • When to Use
  • Trade-offs

18.12.2 Immutable Objects

  • Memory Sharing
  • Thread Safety
  • String Pool Example
  • Benefits

18.12.3 Lazy Initialization

  • On-Demand Creation
  • Memory Savings
  • Double-Checked Locking
  • Holder Pattern

18.12.4 Primitive Types vs Wrappers

  • Memory Overhead
  • Auto-boxing Cost
  • Performance Impact
  • When to Use Each

18.12.5 Collection Sizing

  • Initial Capacity
  • Load Factor
  • Resizing Cost
  • Memory Pre-allocation

18.12.6 String Optimization

  • StringBuilder Usage
  • String Concatenation
  • String Deduplication
  • Compact Strings (Java 9+)

18.13 Memory Best Practices

18.13.1 Design Guidelines

  • Minimize Object Creation
  • Favor Immutability
  • Use Primitives When Possible
  • Proper Collection Sizing
  • Resource Cleanup

18.13.2 Coding Practices

  • Avoid Premature Optimization
  • Profile Before Optimizing
  • Use try-with-resources
  • Clear Collections
  • Avoid String Concatenation in Loops

18.13.3 Architecture Patterns

  • Object Pooling
  • Flyweight Pattern
  • Singleton Pattern
  • Cache Strategies

18.14 OutOfMemoryError

18.14.1 Types of OOME

  • Heap Space
  • Metaspace/PermGen
  • GC Overhead Limit
  • Unable to Create Native Thread
  • Direct Buffer Memory

18.14.2 Diagnosis

  • Heap Dumps
  • GC Logs
  • Error Messages
  • System Resources

18.14.3 Resolution

  • Increase Heap Size
  • Fix Memory Leaks
  • Optimize Code
  • Review Architecture

18.15 Stack Memory Management

18.15.1 Stack Overflow

  • Causes
  • Recursive Calls
  • Deep Call Stacks
  • Stack Size (-Xss)

18.15.2 Stack vs Heap

  • Allocation Speed
  • Lifetime
  • Size Limits
  • Thread Safety

18.16 Native Memory

18.16.1 Off-Heap Memory

  • Direct ByteBuffers
  • Native Allocations
  • Memory-Mapped Files
  • JNI

18.16.2 Direct Memory

  • DirectByteBuffer
  • Advantages
  • Disadvantages
  • -XX:MaxDirectMemorySize

18.17 Memory Monitoring

18.17.1 JMX (Java Management Extensions)

  • MemoryMXBean
  • GarbageCollectorMXBean
  • Runtime Monitoring
  • Memory Pools

18.17.2 Runtime Class

  • totalMemory()
  • freeMemory()
  • maxMemory()
  • gc()

18.17.3 Management Factory

  • Memory Usage
  • GC Statistics
  • Thread Information
  • Class Loading

18.18 Advanced Topics

18.18.1 Compressed Oops

  • Object Pointer Compression
  • Heap Size < 32GB
  • Memory Savings
  • -XX:+UseCompressedOops

18.18.2 Escape Analysis

  • JIT Optimization
  • Stack Allocation
  • Scalar Replacement
  • Lock Elision

18.18.3 NUMA Awareness

  • Non-Uniform Memory Access
  • Multi-Socket Machines
  • -XX:+UseNUMA

Hands-on Exercises

  1. Analyze heap dumps
  2. Create and fix memory leaks
  3. Tune GC parameters
  4. Implement different reference types
  5. Use memory profilers
  6. Optimize object creation
  7. Implement object pooling
  8. Monitor memory usage with JMX
  9. Analyze GC logs
  10. Create OutOfMemoryError scenarios
  11. Implement Cleaner API
  12. Performance tuning exercises

Key Takeaways

  • JVM manages memory automatically
  • Generational GC improves performance
  • Different GC collectors for different needs
  • Memory leaks can occur in Java
  • Proper resource management is crucial
  • Reference types provide flexibility
  • Profiling identifies memory issues
  • Tuning requires understanding trade-offs

Common Mistakes to Avoid

  • Ignoring resource cleanup
  • Static collection accumulation
  • Not removing listeners
  • Overusing finalize()
  • Premature optimization
  • Wrong GC choice
  • Not monitoring memory
  • Ignoring memory leaks

Real-World Applications

  • Enterprise applications
  • High-performance systems
  • Long-running services
  • Memory-constrained environments
  • Big data processing
  • Real-time systems
  • Microservices

Additional Resources

  • Java Performance: The Definitive Guide
  • Java Performance Tuning
  • GC Handbook
  • JVM Specification
  • Memory Profiling Tools Documentation

Assessment

  • Quiz on memory management
  • Practical: Memory leak detection
  • GC tuning exercises
  • Heap dump analysis
  • Performance optimization challenges

Previous Module

Module 17: Advanced Java Features

Next Module

Module 19: Design Patterns