内存优化骚操作之GPU

某主机厂在项目之初对各三方应用提出应用内存要求,要求各应用内存不得超出某个限定值,我们应用拿到的内存限定值为100M,此为背景。

起初我们以dumpsys meminfo查看内存,满足限定值问题不大,后经沟通主机厂要求以top指令的RES内存为实际内存值,关于RES/PSS/USS/VSS可以查看https://www.cnblogs.com/zl1991/p/6644998.html(注:procrank指令需要系统在debug/eng模式编译或者root下才支持),其实最准确的应该是以PSS作为各应用实际占用的内存值,但PSS无指令可循环统计(procrank指令响应时间较长,不适合脚本统计均值和峰值,另因项目本身原因也无法推动要求按PSS作为内存标准)。

过程中我们试过以下方式快速降低内存:

1、作为带大量图片的运营应用,最大内存消耗应该为图片消耗,我们对Glide默认使用skipMemoryCache,即对图片不进行缓存也无法达到限定要求(此过程还发现Glide一个小问题,强制使用DecodeFormat.PREFER_RGB_565无法对png图强制为565格式,最终通过aop方式解决此问题)

2、关闭硬件加速(高版本系统默认开启硬件加速),因RES是包括GPU内存,关闭硬件加速可直接减少GPU内存(通过dumpsys meminfo --pmem可查看GPU显存),带来的负面影响是CPU均值增加,且关闭硬件加速带来一系列显示问题,如动画效果消失,偶现布局或默认图无法展示出,最终弃用该方案。

在方案2上得到启发,同时经过测试,发现空页面的开关会不停增加gpu内存,直到触发gc回收gpu内存才可回归正常,此过程并无任何内存泄露,既然如此我们是否可通过一定策略主动回收GPU内存来降低RES内存均值?

GPU内存相关源码可查看HardwareRenderer,其本身是有隐藏的API trimMemory来进行GPU内存恢复回收,因担心直接反射此方法会带来一系列不可预知问题,我们尽量通过系统本身使用的安全方法来触发,个中曲折不再重复,最后发现其实系统WindowManagerGlobal中有对GPU内存回收的触发,且分不同level触发,最后实测反射WindowManagerGlobal的trimMemory可降低RES均值10-20M左右,基本接近RES限定值,以下为最终使用代码:

try {
    Class<?> threadClazz = Class.forName("android.view.WindowManagerGlobal");
    Method instance = threadClazz.getMethod("getInstance");
    Object object = instance.invoke(threadClazz);
    @SuppressLint("SoonBlockedPrivateApi")
    Method m1 = threadClazz.getDeclaredMethod("trimMemory", int.class);
    m1.invoke(object, TRIM_MEMORY_COMPLETE);
} catch (Exception e) {
    e.printStackTrace();
}

注意,以上方法需在主线程调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值