Optimize HLS playlist parsing by caching regex Matchers#3008
Merged
copybara-service[bot] merged 6 commits intoandroidx:mainfrom Jan 16, 2026
Merged
Optimize HLS playlist parsing by caching regex Matchers#3008copybara-service[bot] merged 6 commits intoandroidx:mainfrom
copybara-service[bot] merged 6 commits intoandroidx:mainfrom
Conversation
Introduce a per-parse regex Matcher cache in HlsPlaylistParser to significantly reduce object allocation overhead during playlist parsing. Problem: Each Matcher object allocates memory in BOTH Java heap and native heap, creating two critical issues in production: 1. Native heap exhaustion: Native allocations are substantial and not subject to normal Java GC pressure. When Matcher objects are created faster than they're garbage collected, the native heap can be exhausted even when Java heap has space available, causing OutOfMemoryError in the native allocator. 2. GC-induced ANRs: Excessive Matcher allocation causes frequent GC cycles. This is particularly severe with MultiView feature (4 concurrent playback sessions) on lower-performance devices, where sustained GC pressure from thousands of short-lived Matcher objects causes Application Not Responding (ANR) events. Both issues are exacerbated by frequent HLS playlist refreshes (every 2-6 seconds), creating continuous allocation pressure. Solution: - Instantiate a MatcherCacheState per parse() call and pass it through private parsing helpers (no ThreadLocal, clear ownership/lifetime) - Employ access-ordered LinkedHashMap as LRU cache (max 32 entries) - Reuse Matcher objects via reset() instead of creating new instances - Eliminate both Java heap AND native heap allocation pressure Performance impact: - Reduces Matcher allocations by >99% in production workloads - Eliminates native heap exhaustion risk from Matcher object churn - Drastically reduces GC frequency and duration, preventing ANRs - Typical cache occupancy: 6-12 patterns (well under 32 limit) - Critical for MultiView and lower-performance devices Testing: - Validated over 2+ hours with production HLS streams - No functional changes to parsing behavior - All existing tests pass
cdc3a1c to
52aea57
Compare
Contributor
|
Thanks! I'm going to send this for internal review now. You may see some more commits being added as I make changes in response to review feedback. Please refrain from pushing any more substantive changes as it will complicate the internal review - thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduce a per-parse regex Matcher cache in HlsPlaylistParser to significantly reduce object allocation overhead during playlist parsing.
Problem:
Each Matcher object allocates memory in BOTH Java heap and native heap, creating two critical issues in production:
Native heap exhaustion: Native allocations are substantial and not subject to normal Java GC pressure. When Matcher objects are created faster than they're garbage collected, the native heap can be exhausted even when Java heap has space available, causing OutOfMemoryError in the native allocator.
GC-induced ANRs: Excessive Matcher allocation causes frequent GC cycles. This is particularly severe with MultiView feature (4 concurrent playback sessions) on lower-performance devices, where sustained GC pressure from thousands of short-lived Matcher objects causes Application Not Responding (ANR) events.
Both issues are exacerbated by frequent HLS playlist refreshes (every 2-6 seconds), creating continuous allocation pressure.
Solution:
Performance impact:
Testing: