优化安卓应用内存的神秘方法以及背后的原理,一般人我不告诉他

安卓应用一般都害怕自己被杀,内存占用高是被杀的重要原因之一,所以大家都想尽各种招数应对,但效果都一般。


但有一招:


WindowManagerGlobal.getInstance().startTrimMemory(TRIM_MEMORY_COMPLETE);


几乎没有人提及。这段时间tos的实战,在通知栏和桌面都有尝试,发现效果还不错,但要掌握好这个函数的用法,需要仔细理解背后的原理,毕竟这个调用相当于在局部时间内让应用的一系列GPU缓存被清理,相当于硬件加速失效。


文章分三大部分,第一大部分用简单的方式描述安卓绘制系统框架,第二大部分说明绘制过程中GPU产生缓存的原因。第三大部分说明startTrimMemory能够清理的GPU缓存以及一些误区。


(一)简介安卓绘制系统框架


安卓绘制系统比较复杂,网上很多文章讲得很细,但不容易抓住核心要点,其实我们只要抓到12个关键的对应关系和概念,就可以掌握清晰基本框架,对debug和性能优化都有价值。


1)一个activity对应一个window,当然,没有activity耶可以有window,比如通知栏,window大家都知道,有各种属性,比如层次,位置等等


2)一个window对应一个surface,surface其实就是一个对graphic buffer进行管理的对象


3)surface的创建是请求surfaceflinger完成的,其实对应的是一块graphicbuffer,gpu和cp都能访问到


4)window上可以有很多的view,可以是一棵view的tree,对于activity来说,顶部的view就是DecorView,activity上所有的view都对应同一个surface


5)相比activity里的view,surfaceview(glsurfaceview)会有自己独立的surface,有自己独立的处理线程,与activity的surface不是同一个


6)activity的view的绘制(打开硬件加速的情况下),其实就是在一个surface上的绘制,最终通过hwui这个so完成,这是在应用端进行的,不是在surfaceflinger这一侧。hwui是硬件绘制的关键库,最关键的是hwui里有一系列GPU缓存,避免在绘制的时候重新再上传图片纹理等GPU绘制相关的数据


7)各个surface还有一个合成的过程,这是在surfaceflinger中完成的


8)每一次activity的view的绘制和surface的合成,都是通过vsync信号触发的,vsync每16.6毫秒触发一次


9)surfaceview(glsurfaceview)的绘制可以不通过vsync来同步,自己的线程独立控制节奏,但是绘制之后的surface的合成,由surfaceflinger统一进行


10)应用侧的surface,无论是view还是surface view对应的,绘制完毕之后,通过eglwapbuffer的方法,将graphicbuffer queue回给surfaceflinger(surfaceflinger合成完毕之后,会上屏,之后会释放出来,让应用侧可以重新使用这些buffer)


11)view做动画的时候,如果子view没有刷新,子view的ondraw可以不被触发,这是动画过程性能高效的一个关键点,以view的hardware layer缓存整体做动画即可,在view做动画的时候如果触发了子view的重新绘制,绘制效率就会降低


12) 目前主流安卓手机,GPU和CPU会共享内存,GPU占用内存多了,留给CPU的就会相应减少,每个进程GPU占用的内存,也会被统计到各个进程的总内存当中,会影响到low memory killer的策略



  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Android 应用开发中,为了提高应用的性能和内存使用效率,可以采取一些优化方法优化四大组件的内存使用。下面是各个组件的内存优化方法的详细解释: 1. Activity 内存优化: - 使用 `android:launchMode` 属性:根据业务需求合理设置 Activity 的启动模式,避免创建多个相同的 Activity 实例。 - 谨慎使用静态成员变量:避免在 Activity 中使用静态成员变量,因为静态变量会常驻内存,容易导致内存泄漏。 - 及时释放资源:在 `onDestroy()` 方法中释放不再需要的资源,如取消注册广播接收器、关闭数据库连接、停止耗时任务等。 2. Service 内存优化: - 使用启动方式合理的 Service:根据业务需求选择合适的启动方式,如使用 `startService()` 启动后及时调用 `stopSelf()` 或 `stopService()` 停止服务。 - 使用 IntentService:IntentService 是一种自动停止的服务,当任务执行完毕后会自动停止服务,避免忘记手动停止服务。 - 优化线程使用:合理使用线程池来管理线程,避免创建过多的线程,控制线程数量。 3. BroadcastReceiver 内存优化: - 尽早取消注册广播接收器:在不需要接收广播时,及时调用 `unregisterReceiver()` 方法取消注册广播接收器。 - 使用动态注册:根据需要动态注册广播接收器,避免静态注册导致无法及时取消注册。 4. ContentProvider 内存优化: - 懒加载数据:在需要时再去加载数据,避免一次性加载所有数据。 - 使用 CursorLoader:CursorLoader 是一个异步加载数据的工具类,可以在后台线程中加载数据,避免阻塞主线程。 此外,通用的内存优化方法包括: - 避免内存泄漏:合理使用对象的引用,避免对象持有不必要的引用导致内存泄漏。 - 使用资源合理:避免过度使用大量的 Bitmap、Drawable 等资源,及时释放不再使用的资源。 - 使用轻量级的数据结构:选择合适的数据结构来存储和处理数据,避免占用过多的内存。 这些方法可以帮助你优化四大组件的内存使用,提高应用的性能和内存效率。但是需要根据具体的业务需求和场景来选择适合的优化方法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值