【Android 性能优化:内存篇】——ExoPlayer 释放后内存没有恢复问题探索

背景

最近笔者承接项目的内存优化指标,在内存调研的过程中发现项目中视频播放结束后,内存没有恢复到播放前到水平。项目中用的 EXO 版本为2.19.1,并且笔者自己也写了个简单的 Demo,发现也是如此。虽然有一些偏门方法可以优化,但是暂时还是未能正面突破,各位看官,如果有什么idea,欢迎留言多多指教~

分析

笔者的 Demo 如下

 api 'com.google.android.exoplayer:exoplayer:2.19.1'

VideoTestFragment.java 

package com.mikel.projectdemo.uiframework;import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.ui.PlayerView;
import com.mikel.projectdemo.R;
import org.jetbrains.annotations.NotNull;public class VideoTestFragment extends Fragment {public static VideoTestFragment build() {return new VideoTestFragment();}private Context mContext;private SimpleExoPlayer mSimpleExoPlayer;private PlayerView playerView;@Overridepublic View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {mContext = getActivity();View rootView = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_video_item, null, true);initUI(rootView);return rootView;}private void initUI(View rootView) {mSimpleExoPlayer = new SimpleExoPlayer.Builder(getActivity()).build();// 准备要播放的媒体资源MediaItem mediaItem = MediaItem.fromUri("https://vfx.mtime.cn/Video/2019/01/15/mp4/190115161611510728_480.mp4");mSimpleExoPlayer.setMediaItem(mediaItem);// 将ExoPlayer关联到要显示视频的ViewplayerView = rootView.findViewById(R.id.player_view);playerView.setPlayer(mSimpleExoPlayer);}public void startPlay() {// 准备播放器mSimpleExoPlayer.prepare();mSimpleExoPlayer.play();}/*** 停止播放*/public void stopPlay() {pausePlay();if(mSimpleExoPlayer != null) {mSimpleExoPlayer.release();mSimpleExoPlayer = null;}}public void resumePlay() {if(mSimpleExoPlayer != null) {mSimpleExoPlayer.setPlayWhenReady(true);} else {startPlay();}}public void pausePlay() {if(mSimpleExoPlayer != null) {mSimpleExoPlayer.setPlayWhenReady(false);}}@Overridepublic void onDestroyView() {super.onDestroyView();stopPlay();}@Overridepublic void onResume() {super.onResume();resumePlay();}@Overridepublic void onStop() {super.onStop();pausePlay();}
}

 fragment_video_item.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.google.android.exoplayer2.ui.PlayerViewandroid:id="@+id/player_view"android:layout_width="match_parent"android:layout_height="match_parent"></com.google.android.exoplayer2.ui.PlayerView>
</FrameLayout>

VideoTestActivity.java

public class VideoTestActivity extends AppCompatActivity {public static void startActivity(Context context) {Intent intent = new Intent(context, VideoTestActivity.class);context.startActivity(intent);}@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_video_test);FragmentManager fragmentManager = getSupportFragmentManager();VideoTestFragment videoTestFragment = VideoTestFragment.build();FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();fragmentTransaction.add(R.id.fragment_container, videoTestFragment);fragmentTransaction.commit();}
}

activity_video_test.xml 

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><FrameLayoutandroid:id="@+id/fragment_container"android:layout_width="match_parent"android:layout_height="match_parent"></FrameLayout>
</FrameLayout>

 打开播放页面前和播放后关闭页面,内存水位如下:

内存水位简直毫无波澜,笔者也在 ExoPlayer 上发现不少相关 Issue:

https://github.com/google/ExoPlayer/issues/9755

 Memory leak · Issue #1855 · google/ExoPlayer · GitHub

issue 里有一个方法是说在页面onDestroy的时候不仅释放Exoplayer, 还需要加上 simpleExoPlayerView.setPlayer(null),并且把 simpleExoPlayerView也设置为空,笔者尝试了下,内存水位依旧没有太大变化

解决方案探索

方案1 独立进程

业务允许的情况下,把播放页面设置成独立进程,

        <activity android:name=".video.VideoTestActivity"android:process=":video">

退出页面后调用

android.os.Process.killProcess(android.os.Process.myPid());

 该方案适合播放场景单一,使用Activity 来承接视频播放,播放结束后少频繁进入播放页面

方案 2 主动触发 gc

如果业务限制,无法把播放页面放到独立进程,尝试下 VideoFragment onDestroy 的时候主动 Runtime.getRuntime().gc()

该方案剑走偏峰,也是适合播放场景单一,不是频繁打开播放页面的场景,否则频繁手动 gc 可能带来卡顿的性能问题。

各位看官,如果对 ExoPlayer 研究深入或者有什么idea,欢迎留言多多指教~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/486361.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Graphpad Prism10.2.0(329) 安装教程 (含Win/Mac版)

GraphPad Prism GraphPad Prism是一款非常专业强大的科研医学生物数据处理绘图软件&#xff0c;它可以将科学图形、综合曲线拟合&#xff08;非线性回归&#xff09;、可理解的统计数据、数据组织结合在一起&#xff0c;除了最基本的数据统计分析外&#xff0c;还能自动生成统…

Vue 3.0中Tree shaking特性

在 Vue 3.0 中&#xff0c;引入了更好的 Tree shaking 特性&#xff0c;使得在使用 Vue 3 的项目中能够更加高效地进行代码精简和优化。 Tree shaking 是指在打包过程中通过静态分析&#xff0c;去除未使用的代码&#xff08;未被引用的模块或函数&#xff09;&#xff0c;从而…

JavaScript从零写网站《一瞬》开发日志20240223

产品介绍 一个无需注册能随时发布图片并配一段文字介绍的app&#xff0c;有时间线&#xff0c;用户在主页面向下滑动&#xff0c;可以看到被发布的若干图片&#xff0c;并且能够在每一个发布处做基本互动——评论&#xff0c;点赞 编程语言 本产品使用htmlcssJavaScript开发…

SQL表(字段)操作

目标&#xff1a;掌握数据库和字段的相关操作指令&#xff0c;熟练运用这些指令完成数据表的增删改查 创建数据表 显示数据库 查看表结构 更改数据表 更改字段 删除数据表 1、创建数据表 目标&#xff1a;了解数据表创建语法&#xff0c;掌握创建规则 概念 创建数据表:根…

Sora----打破虚实之间的最后一根枷锁----这扇门的背后是人类文明的晟阳还是最后的余晖

目录 一.Sora出道即巅峰 二.为何说Sora是该领域的巨头 三.Sora无敌的背后究竟有怎样先进的处理技术 1.Spacetime Latent Patches 潜变量时空碎片&#xff0c;建构视觉语言系统 2.扩散模型与Diffusion Transformer&#xff0c;组合成强大的信息提取器 3.DiT应用于潜变量时…

iPaaS生成数据库接口只要60秒?

“iPaaS生成数据库接口只要60秒&#xff1f;” 关于“iPaaS生成数据库接口只要60秒&#xff1f;”的说法&#xff0c;这实际上反映了iPaaS解决方案的一个重要优势&#xff1a;高效率。确实&#xff0c;借助iPaaS平台的现成集成工具和模板&#xff0c;用户可以迅速创建连接到特…

抖音小店无货源真的靠谱吗?发展前景如何?2024年值得做吗?

大家好&#xff0c;我是电商花花。 我们通常说的抖音小店无货源就是利用产品之间的信息差、利润差来赚取商品的差价。 无货源模式就是即使没有货源&#xff0c;也能做抖音小店&#xff0c;前期店铺起店&#xff0c;我们需要大量的出单量和数据&#xff0c;我们才能快速把店铺…

01_02_mysql06_(视图-存储过程-函数(变量、流程控制与游标)-触发器)

视图 使用 视图一方面可以帮我们使用表的一部分而不是所有的表&#xff0c;另一方面也可以针对不同的用户制定不同的查询视图。比如&#xff0c;针对一个公司的销售人员&#xff0c;我们只想给他看部分数据&#xff0c;而某些特殊的数据&#xff0c;比如采购的价格&#xff0…

RTP 实时运输协议

目录 1 实时运输协议 RTP 1.1 RTP 的层次 1.2 RTP 分组的首部格式 2 实时运输控制协议 RTCP 2.1 RTCP 分组 1 实时运输协议 RTP 实时运输协议 RTP (Real-time Transport Protocol) 为实时应用提供端到端的运输&#xff0c;但不提供任何服务质量的保证。 需要发送的多媒体…

ssm+springmvc基于springboot的宠物领养系统的设计与实现_j5fk4

宠物领养系统主要是为了提高管理员的工作效率&#xff0c;满足管理员对更方便、更快、更好地存储所有信息和数据检索功能的要求。通过对多个类似网站的合理分析&#xff0c;确定了宠物领养系统的各个模块。考虑到用户的可操作性&#xff0c;经过深入调查研究&#xff0c;遵循系…

StringTable 字符串常量池

参考&#xff1a;javaGuide 字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串&#xff08;String 类&#xff09;专门开辟的一块区域&#xff0c;主要目的是为了避免字符串的重复创建 String的不可变性 1.通过字面量的方式&#xff08;区别于new&#xff09;给一个…

GPT+Python+GEE+ENVI高光谱,多光谱等成像遥感技术应用

原文链接&#xff1a;GPTPythonGEEENVI高光谱&#xff0c;多光谱等成像遥感技术应用https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247594986&idx2&sn770b456d434fdbada22e425b35affe08&chksmfa82320dcdf5bb1b9838b03e13381bdf38ea1b24ebc03526293756a…