You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rockchip机顶盒ExoPlayer播放4K视频遇内存不足问题求助

Rockchip机顶盒ExoPlayer播放特定4K视频内存不足(OOM)问题排查与解决

问题场景

  • 在Rockchip机顶盒设备上使用ExoPlayer播放本地4K视频,全高清视频及多数4K视频播放正常,但少数4K视频会出现严重卡顿,最终播放冻结并抛出内存不足错误
  • ExoPlayer官方演示应用可正常播放该问题视频,但自身应用因需同时处理视频下载、WebSocket长连接等任务,内存占用比演示应用高,但理论上仍应支持播放
  • 转码问题视频后可正常播放

错误日志

GC及内存限制日志

D/EventLogger: videoSize [eventTime=1.49, mediaPos=0.00, window=0, period=0, 3840, 2160]
2022-11-11 11:21:32.323 13639-13639/com.example.package D/EventLogger: renderedFirstFrame [eventTime=1.49, mediaPos=0.00, window=0, period=0, Surface(name=null)/@0x1dcfafd]
2022-11-11 11:21:32.341 13639-13639/com.example.package D/EventLogger: state [eventTime=1.51, mediaPos=0.05, window=0, period=0, READY]
2022-11-11 11:21:32.341 13639-13639/com.example.package I/VideoFragment: onPlayerStateChanged: 3
2022-11-11 11:21:32.342 13639-13639/com.example.package D/EventLogger: isPlaying [eventTime=1.51, mediaPos=0.05, window=0, period=0, true]
2022-11-11 11:21:32.610 13639-13650/com.example.package I/art: Clamp target GC heap from 203MB to 192MB
2022-11-11 11:21:32.636 13639-13714/com.example.package I/art: Waiting for a blocking GC Alloc
2022-11-11 11:21:32.644 13639-13714/com.example.package I/art: WaitForGcToComplete blocked for 7.544ms for cause Alloc
2022-11-11 11:21:32.644 13639-13714/com.example.package I/art: Starting a blocking GC Alloc
2022-11-11 11:21:32.644 13639-13714/com.example.package I/art: Starting a blocking GC Alloc

(后续存在大量blocking GC Alloc日志)

OOM错误堆栈

2022-11-11 11:10:51.403 13452-13535/com.example.package E/LoadTask: OutOfMemory error loading stream
      java.lang.OutOfMemoryError: Failed to allocate a 65548 byte allocation with 53032 free bytes and 51KB until OOM
        at com.google.android.exoplayer2.upstream.DefaultAllocator.allocate(DefaultAllocator.java:102)
        at com.google.android.exoplayer2.source.SampleDataQueue.preAppend(SampleDataQueue.java:233)
        at com.google.android.exoplayer2.source.SampleDataQueue.sampleData(SampleDataQueue.java:176)
        at com.google.android.exoplayer2.source.SampleQueue.sampleData(SampleQueue.java:590)
        at com.google.android.exoplayer2.extractor.TrackOutput.sampleData(TrackOutput.java:157)
        at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.readSample(Mp4Extractor.java:652)
        at com.google.android.exoplayer2.extractor.mp4.Mp4Extractor.read(Mp4Extractor.java:259)
        at com.google.android.exoplayer2.source.BundledExtractorsAdapter.read(BundledExtractorsAdapter.java:127)
        at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1039)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:412)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)

解决措施

1. 限制ExoPlayer内存分配

针对DefaultAllocator设置最大分配内存,避免样本数据占用过多内存:

// 初始化Allocator,设置单个分配块大小及最大总分配内存
DefaultAllocator allocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE);
allocator.setMaxAllocationBytes(10 * 1024 * 1024); // 可根据设备性能调整,例如10MB

// 将配置好的Allocator传入媒体源工厂
ProgressiveMediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory(
    new DefaultDataSourceFactory(context, Util.getUserAgent(context, "YourAppName")),
    new DefaultExtractorsFactory())
    .setAllocator(allocator);

2. 优化应用自身内存占用

因应用同时运行下载、WebSocket等任务,需主动释放闲置资源:

  • 视频播放期间,暂停下载任务的非必要线程,播放结束后恢复
  • WebSocket连接复用实例,避免冗余创建;闲置时清理未使用的缓存数据
  • 实现ComponentCallbacks2接口,在onTrimMemory回调中主动释放非必要资源(如缓存图片、闲置对象)

3. 强制硬件解码减少内存开销

问题视频可能因软件解码占用过多内存,可强制ExoPlayer使用硬件解码:

DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context)
    .setEnableDecoderFallback(false) // 禁用软件解码降级
    .setPreferredVideoRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER);

SimpleExoPlayer player = new SimpleExoPlayer.Builder(context, renderersFactory).build();

4. 调整应用堆内存限制

从日志看出应用堆内存被限制在192MB,可在AndroidManifest.xml中启用大堆模式(仅作为临时缓解,优先优化内存使用):

<application
    ...
    android:largeHeap="true">
</application>

内容的提问来源于stack exchange,提问作者Marco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 07:50:25