Skip to content

Conversation

@PascalThuet
Copy link

@PascalThuet PascalThuet commented Feb 1, 2026

Summary

Implements a bounded LRU (Least Recently Used) cache in InitCache to prevent memory leaks during long playback sessions with multiple periods or stream switches.

Changes

InitCache.js

  • Added MAX_CACHE_SIZE = 50 constant
  • Implemented LRU eviction when cache exceeds limit
  • Added removeStream(streamId) method for explicit cleanup
  • Added getStats() method for debugging/testing
  • Cache now tracks access order for proper LRU behavior

MediaPlayer.js

  • Exposed getInitCache() method for testing access

samples/cache/initcache-test.html

  • Comprehensive test page with 3 test modes
  • Report generation for test results
  • Before/after branch comparison feature

Test Results ✅

Comparison: development vs fix/initcache-lru-limit

Metric development This PR
Entries after 100 insertions 100 (unbounded) 50 (capped)
LRU eviction active ❌ NO ✅ YES
Memory leak risk ⚠️ YES ✅ Controlled

Test 3: Cache Overflow (Synthetic) Results

Branch: development (without fix)

Entries Inserted: 100
Max Allowed: 50
Final Entries: 100
LRU Working: ❌ NO
Overall: ❌ SOME TESTS FAILED

Branch: fix/initcache-lru-limit (with fix)

Entries Inserted: 100
Max Allowed: 50
Final Entries: 50
LRU Working: ✅ YES
Overall: ✅ ALL TESTS PASSED

Test Page

A test page is included at samples/cache/initcache-test.html with three test modes:

Test 1: Quality Switch Stress Test

  • Cycles through all quality levels 10 times
  • Generates many init segment loads
  • Verifies cache doesn't grow unbounded

Test 2: Stream Switch Stress Test

  • Switches between 3 different streams 5 times each
  • Simulates multi-content playback scenarios
  • Tests LRU eviction with different stream IDs

Test 3: Cache Overflow Test (Synthetic)

  • Directly inserts 100 entries into cache
  • Verifies LRU eviction at MAX_CACHE_SIZE limit
  • Most direct validation of the fix

How to Run Tests

# 1. Build
npm run build

# 2. Serve
npm run dev

# 3. Open test page
http://localhost:3000/samples/cache/initcache-test.html

# 4. Run any of the 3 tests
# 5. Enter branch name and click "Generate Report"
# 6. Run on different branch and click "Compare Reports"

Design Decisions

  1. Cache size of 50: A conservative default that should cover most use cases

    • Typical content has multiple representations per stream
    • 50 entries should cover several recent streams
    • Can be made configurable via Settings if needed
  2. LRU vs. TTL: LRU chosen because:

    • Init segments don't expire, they're valid for the stream duration
    • LRU naturally evicts least-used entries
    • No timer overhead
  3. removeStream() method: Allows explicit cleanup when a stream ends

    • Can be called by StreamProcessor on stream completion
    • Optional optimization, not required for correctness

Expected Impact

Scenario Before (development) After (this PR)
Long multi-period playback Cache grows unbounded Cache capped at 50 entries
Memory usage Grows linearly Bounded (~50-500KB max)
Smart TV stability Potential OOM Stable

Testing Checklist

  • Existing unit tests pass
  • Build succeeds (lint passes)
  • Test page included with 3 test modes
  • getStats() method for monitoring
  • Before/after comparison validated
  • Test with real multi-period content (recommended)
  • Memory profiling comparison (recommended)

Breaking Changes

None. Cache behavior is transparent to consumers.

🤖 Generated with Claude Code

Fixes #4932

InitCache now enforces a maximum of 50 entries using LRU eviction
to prevent unbounded memory growth during multi-period playback
or frequent stream switches.

Changes:
- Add MAX_CACHE_SIZE constant (50 entries)
- Implement LRU eviction when cache exceeds limit
- Add removeStream() method for explicit cleanup
- Track access order for proper LRU behavior

This addresses memory accumulation on long-form content with many
periods, particularly important for Smart TV devices with limited RAM.

Fixes Dash-Industry-Forum#4932
@PascalThuet PascalThuet force-pushed the fix/initcache-lru-limit branch from a31184a to f0ca62a Compare February 1, 2026 09:01
PascalThuet and others added 2 commits February 1, 2026 19:00
- Add getStats() method to InitCache for debugging/testing
- Expose getInitCache() in MediaPlayer API
- Create comprehensive test page at samples/cache/initcache-test.html

Test page includes:
1. Quality Switch Stress Test - cycles through quality levels
2. Stream Switch Stress Test - switches between multiple streams
3. Cache Overflow Test (Synthetic) - directly tests LRU eviction

Also includes:
- Real-time cache statistics monitoring
- Memory profiling instructions for Chrome DevTools
- Metrics export functionality

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add test results storage for all 3 test modes
- Add generateReport() function with formatted output
- Add compareReports() for side-by-side branch comparison
- Store reports in localStorage for persistence
- Add UI controls for branch name input and report buttons

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@dsilhavy dsilhavy added this to the 5.2.0 milestone Feb 3, 2026
@dsilhavy dsilhavy self-assigned this Feb 3, 2026
@dsilhavy dsilhavy moved this to Selected for Development in dash.js Version 5.2.0 Feb 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Selected for Development

Development

Successfully merging this pull request may close these issues.

Memory leak: InitCache grows unbounded during multi-period playback

2 participants