Skip to content

fix: implement memory-based throttle to prevent OOM during downloads#2786

Merged
fire-light43 merged 2 commits into
recloudstream:masterfrom
asheeshsahu7300:fix/downloader-oom
May 12, 2026
Merged

fix: implement memory-based throttle to prevent OOM during downloads#2786
fire-light43 merged 2 commits into
recloudstream:masterfrom
asheeshsahu7300:fix/downloader-oom

Conversation

@asheeshsahu7300
Copy link
Copy Markdown
Contributor

Viewed AndroidManifest.xml:9-18

Here is a detailed description you can use for the fix: implement memory-based throttle to prevent OOM during downloads Pull Request:


Description: Implement Memory-Based Throttle to Prevent OOM During Downloads

This PR addresses reported crashes (rebooting into safe mode) that occur during large downloads, particularly on newer Android versions like Android 16.

The Problem

CloudStream uses a parallel downloading strategy to maximize speed. However, previously there was no limit on how far ahead the network jobs could download compared to what was successfully written to the disk.

If the disk write speed was slower than the network speed (common with slow SD cards or high-speed fiber), or if a specific segment was delayed while subsequent segments were downloaded successfully, the app would buffer the out-of-order data in RAM. For large files, this buffer could grow to several hundred megabytes, triggering an OutOfMemory (OOM) error and crashing the app.

The Solution

Instead of an unbounded lookahead, this PR implements a memory-based throttle that monitors the gap between downloaded data and written data.

Key Changes:

  1. Buffered Data Monitoring: Added a check in the download loop that calculates metadata.bytesDownloaded - metadata.bytesWritten. This represents the exact amount of data currently held in the RAM buffer (pendingData).
  2. Adaptive Throttling: If the buffer exceeds 100MB, the downloader pauses starting new segment requests and waits for the disk writer to catch up.
  3. Thread Safety:
    • The metadata check is performed within the existing fileMutex.withLock to ensure data consistency.
    • The delay is executed outside the lock to prevent blocking other critical operations or causing deadlocks.
  4. Preserved Logic: The fix integrates seamlessly with the existing iterator-based download strategy without requiring major structural changes to DownloadManager.kt.

Results

  • Stability: RAM usage is now capped at approximately 100MB of download buffer, regardless of the file size or download speed.
  • Progress Integrity: Since we no longer allow the download to get excessively far ahead of the disk write, the "progress shifting back" after a crash is significantly reduced.

AI Usage Disclosure

This fix was developed with AI assistance to identify the root cause of the memory leak in the parallel download queue. Following review from @fire-light43, the implementation was refined to use the existing bytesDownloaded and bytesWritten metadata for a more lightweight and robust solution.


Copy link
Copy Markdown
Contributor

@fire-light43 fire-light43 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very well made! Thank you for the contribution.

I reduced the limit to 50MB to be on the safer side, it's a soft limit after all.

@fire-light43 fire-light43 merged commit 03eb6cc into recloudstream:master May 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants