Camera2内存泄漏修复

最近公司想要使用Camera2来替换线上的旧版相机,功能调研过程中发现Camera2在很多机器上都会有奇怪的内存泄漏,比较明显的时候可能有100M+,比较常见的是表现为内存释放不及时(上涨一段时间后会有一次下降),这种现象在旧版Camera时是不存在的,内存图如下。

使用Android studio抓取内存Profile后如下图所示,未释放内存主要是由native方法allocate_camera_metadata所分配,追溯堆栈到java层应该为CameraMetaDataNative.set方法,而CameraMetaDataNative为CaptureResult的成员变量,通过跟踪源码以及打印onCaptureCompleted方法所返回的TotalCaptureResult可知该对象每帧hash都不一样,推测是每帧都在创建一个新的对象然后由垃圾回收器来自动回收。但是由于该java对象占用内存对象较小,所以较长时间都不会触发gc,而由于是在finalize()方法中释放native资源所以导致了native资源的释放不及时。

上面的图文字可能比较小看不清,所以又截了一张详细堆栈图。

解决方案要想解决该问题需要做的就是在TotalCaptureResult不需要使用后手动调用释放接口。

public class BugFix {

    static Field sTargetField;
    static Method sTargetMethod;

    public static void recycle(TotalCaptureResult tcr) {
        try {
            if (sTargetField == null) {
                sTargetField = tcr.getClass().getSuperclass().getDeclaredField("mResults");
                sTargetField.setAccessible(true);
            }
            if (sTargetMethod == null) {
                Class clazz = Class.forName("android.hardware.camera2.impl.CameraMetadataNative");
                Method[] methodList = clazz.getDeclaredMethods();
                Method close = null;
                Method finalize = null;
                for(Method m: methodList) {
                    if (m.getName().contains("close")) { // 本地测试发现部分机器(Redmi k70)无法找到此方法,只能调用finalize
                        close = m;
                        break;
                    } else if (m.getName().contains("finalize")) {
                        finalize = m;
                    }
                }
                sTargetMethod = close == null? finalize: close;
                if (sTargetMethod == null) {
                    return;
                }
                sTargetMethod.setAccessible(true);
            }
            sTargetMethod.invoke(sTargetField.get(tcr));
        } catch (NoSuchFieldException | ClassNotFoundException | InvocationTargetException |
                 IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}

效果确认:通过解决前后数据对比,在fps相近情况下修复后在cpu/内存/cpu温度方面都有所优化。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值