Android Raphael使用(专治native 内存泄漏)

news2024/12/31 6:16:18

1.前期准备

在项目根目录build.gradle中,添加仓库地址:

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

2.案例实践

构建一个新的Library Module,其中build.gradle中添加依赖:

dependencies {
    implementation 'com.github.bytedance:memory-leak-detector:0.2.1'
}

Raphael API使用

Raphael是有两种方式可以监控进程中native内存: 其一是通过java代码来实现,其二是通过adb shell 发送广播命令行来控制。

启动监控

// 监控指定的so
Raphael.start(
    Raphael.MAP64_MODE|Raphael.ALLOC_MODE|0x0F0000|1024,
    "/storage/emulated/0/raphael", // 需要申请读写sdcard权限
    null      
);

参数

  • 第一个参数: 指定模式
  • 第二个参数: native内存文件存放的目录,若是sdcard,则需要申请权限
  • 第三个参数:指定监控的so库。比如,监控libxxx.so中内存,则传入 ".*libxxx\\.so$"; 若传入null ,则监控进程中全部so库;

等同于adb shell 命令行实现:

## 监控整个进程(RaphaelReceiver 组件所在的进程)
## 0x0CF0400=Raphael.MAP64_MODE|Raphael.ALLOC_MODE|0x0F0000|1024
adb shell am broadcast -a com.bytedance.raphael.ACTION_START -f 0x01000000 --es configs 0xCF0400

打印内存

// 代码控制
Raphael.print();

等同于:

## 本地广播
adb shell am broadcast -a com.bytedance.raphael.ACTION_PRINT -f 0x01000000

更多API详情,请阅读Raphael API使用

实现思路

为了灵活使用,建议使用两者配合使用,首先通过java 代码方式 在Application中启动监控整个进程,其次,涉及业务场景后,通过adb shell 来打印内存,缓存到指定目录下。

代码实现

基于raphael api ,简单封装下,代码如下:

public class RaphaelUtils {

    /**
     * 监听整个进程中全部的so库内存泄漏
     */
    public static void monitorAllNativeSo(){
        String regexSo=null;
        monitorNativeSo(regexSo);
    }

    /**
     * 监控指定的 so 库内存泄漏
     * @param regexSo
     */
    public static void monitorNativeSo(String regexSo){
        final  String spaceDir="/storage/emulated/0/raphael";
        monitorNativeSo(spaceDir,regexSo);
    }
    /**
     * 用于监听so内存泄漏,存储到指定位置
     * 也可以通过adb shell 命令行来执行(灵活使用):
     * adb shell am broadcast -a com.bytedance.raphael.ACTION_START -f 0x01000000 --es configs 0xCF0400 --es regex ".*libXXX\\.so$"
     *
     *
     * @param spaceDir  记录泄漏的存放地址,这里必须获取 读写权限。
     *                  比如:"/storage/emulated/0/raphael"
     * @param regexSo  传入null ,监听全部so库。
     */
    public static void monitorNativeSo(String spaceDir,String regexSo){

        // 监控整个进程
        Raphael.start(Raphael.MAP64_MODE|Raphael.ALLOC_MODE|0x0F0000|1024,
                spaceDir,
                regexSo
        );
    }

    /**
     * 打印内存泄漏的信息,存储导致sdcard中
     *
     * 也可以通过adb shell 命令行来执行(灵活使用):
     * adb shell am broadcast -a com.bytedance.raphael.ACTION_PRINT -f 0x01000000
     */
    public static void printNativeLeak(){
        Raphael.print();
    }

    /**
     * 停止监听
     * 也可以通过adb shell 命令行来执行(灵活使用):
     * adb shell am broadcast -a com.bytedance.raphael.ACTION_STOP -f 0x01000000
     */
    public static void stopMonitor(){
        Raphael.stop();
    }
}

在Application中onCreate()指定监控so库:

    public void onCreate() {
        super.onCreate();
        RaphaelUtils.monitorNativeSo(    ".*libAppPlayx\\.so$");
    }

构建apk 进行安装,启动后,赋予读写权限,进行一些列的业务操作,进行adb shell 命令操作,打印内存情况:

adb shell am broadcast -a com.bytedance.raphael.ACTION_PRINT -f 0x01000000

内存文件将缓存在Raphael.start()中第二个传入的目录下,这里是"/storage/emulated/0/raphael"

在这里插入图片描述

将其拷贝出来,通过adb pull 也来拷贝。

配置Python 环境

report 文件是无法直接进行获取native 堆栈信息,需要借用raphael.py 进行转换。先配置python的环境,在官网下载python 3.x ,进行默认安装。

在命令中执行python ,检查是否安装成功:

在这里插入图片描述

为了方便,将需要的几个文件都拷贝到同一个目录中:

  • so对应addr2line工具
  • 带有符号表的so库
  • report文件
  • py脚本(raphael.py/mmap.py)

执行命令行如下,若是report 过大,执行会过长:
在这里插入图片描述
执行完后,会在同个目录中生成leak-doublets.txt,里面包含内存信息和堆栈信息。
在这里插入图片描述

打开默认生成leak-doublets.txt:

  204,364,751	totals // 单指raphael拦截到的未释放的虚拟内存总和
  204,364,751	libAppPlayJNI.so  //该库未释放的内存

0x0000007865600000, 58741400, 1 
0x0000000001171d4c /data/app/~~vZjWn3Y0HAlsqNnxySQWjg==/com.xxx.miniworld-J6zXyou6Nnd_y7pG4EZo7g==/lib/arm64/libAppxxxJNI.so (F:/minichina/miniad/xxxx/OgreSingleton.h:110)
....

信息解读:

内存和调用次数

0x0000007865600000, 58741400, 1  

0x0000007865600000是report里此堆栈第一次分配出的内存地址,58741400是report里此堆栈的内存总和, 1是report里此堆栈的总次数

native的调用栈

0x0000000001171d4c /data/app/~~vZjWn3Y0HAlsqNnxySQWjg==/com.xxx.miniworld-J6zXyou6Nnd_y7pG4EZo7g==/lib/arm64/libAppxxxJNI.so (F:/minichina/miniad/xxxx/OgreSingleton.h:110)

根据以上信息,就很好分析哪些native 对象占用内存,在某些业务场景下该进行释放。

3.借鉴

在这里插入图片描述

在这里插入图片描述

raphael其中有一个很好的借鉴方面,通过adb shell 命令行发送广播命令,从而执行一些逻辑操作。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

gitlab-runner搭建CI/CD

1. 背景 每次发布代码,需要连接服务器更新代码,进行部署,比较繁琐,浪费时间。方案有jenkins或gitlab-runner。由于代码仓库是gitlab并且只需要自动部署,不需要其他额外功能,这里选择使用gitlab-runner。 …

【React】三.React组件基础学习

目录 React组件介绍 React组件的两种创建方式 使用函数创建组件 函数组件 渲染函数组件 示例 使用类创建组件 抽离为独立的JS文件 步骤 问题记录 React事件处理 事件绑定 记录问题 事件对象 有状态组件和无状态组件 无状态组件(木偶组件)…

XSS(Cross Site Scripting)攻击简介

环境 Ubuntu 22.04IntelliJ IDEA 2022.1.3JDK 17.0.3.1Spring Boot 3.0.1Firefox 108.0.2 问题和分析 在IntelliJ IDEA中创建Spring Boot项目 test0116 ,并选中 Spring Web 依赖。 在 src/main/java 下创建 MyController.java 如下: package com.ex…

Redis缓冲区不会还有人不知道吧?

1 简介 缓冲区,用一块内存空间暂时存放命令数据,以免因 数据和命令的处理速度<发送速度而导致数据丢失和性能问题。但缓冲区的内存空间有限,若持续: 往里写数据速度>从里读数据速度会导致缓冲区需越来越…

ATGM332D-5N卫星导航模块介绍

ATGM332D-5N卫星导航模块简介ATGM332D-5N系列模块是12X16 尺寸的高性能BDS/GNSS 全星座定位导航模块系列的总称。该系列模块产品都是基于中科微第四代低功耗GNSS SOC单芯片—AT6558,支持多种卫星导航系统,包括中国的BDS(北斗卫星导航系统&…

BFS的入门与应用

目录 一、前言 二、BFS原理 二、BFS与最短路径 1、最短路径问题用BFS 2、迷宫(2019年省赛,填空题,lanqiaoOJ题号602) (1)字典序最小的最短路径 (2)输出路径的两种方法 三、B…

拉伯证券|今年首批游戏版号发放,机构看好春节行业景气度恢复

2023年第一批游戏版号发放。 昨日晚间,国家新闻出版署发布1月国产网络游戏审批信息,共88款游戏获批,其我国内各大游戏龙头均有所收成,包含腾讯《黎明觉悟:活力》、网易《逆水寒》(移动版)、完美…

数据治理:数据治理之道-组织机制-敏捷的治理组织

参考《一本书讲透数据治理》、《数据治理》等 组织机制:敏捷的治理组织 数据、组织、软件平台,是企业数字化转型面临的三座大山 数据:数据是企业数字化转型的根本驱动力之一,数字化转型中的企业必须做好数据治理与应用&#xff…

8Manage:分散的软件正在扼杀公司的生产力

在企业领域,数字化不仅仅是指工具能力,而是指用户如何很好地应用他们的知识来做决策,培养关系,建立声誉,以及动员同事、团队。几十年来,企业已经部署了生产力、搜索和协作平台,以提高员工和业务…

使用 tslib 库

tslib 是专门为触摸屏设备所开发的 Linux 应用层函数库,并且是开源。tslib 为触摸屏驱动和应用层之间的适配层, 它把应用程序中读取触摸屏 struct input_event 类型数据(这是输入设备上报给应用层的原始数据)并进行解析的操作过程…

ceres学习笔记(三)

学习了example中pose_graph_3d的部分,记录一下学习过程。 前言: 翻译一下readme里面的内容: ... 该示例还说明了如何将 Eigen 的几何模块与 Ceres 的自动微分功能结合使用。 为了表示方向,我们将使用 Eigen 的四元数&#xff…

测试开发 | Pytest 结合 Allure 生成测试报告

本文节选自霍格沃玆测试学院测试开发内部教材,进阶学习文末加群! 测试报告在项目中是至关重要的角色,一个好的测试报告: 可以体现测试人员的工作量; 开发人员可以从测试报告中了解缺陷的情况; 测试经理可…

锂电产业如何利用视觉检测系统降本增效?

导语:机器视觉检测已在锂电池生产的各个环节中,为产品产量与质量提供可靠保障。维视智造作为锂电池视觉检测系统提供商,为企业提供专业、系统、稳定的锂电行业解决方案,可保证0漏检,确保安全生产,全面提升生…

炫酷 RGB 之.NET nanoFramework 点灯大师

前面介绍了 .NET nanoFramework 入门,本文继续以微雪的 ESP32-S2-Pico 为例介绍 .NET nanoFramework 的开发:控制 ESP32 板载 RGB 灯 和 外接 RGB 灯。内容包含 状态灯的意义、WS2812 、HSV、PWM 等相关知识。 文章目录1. 背景2. 状态灯的意义3. 板载 LE…

萌新如何使用printf函数?

🐎作者的话 如果你搜索输入输出函数,那么你会看到输入输出流、Turbo标准库、标准输出端、stdout什么什么乱七八糟的,作为一个萌新,哪懂这些? 本文介绍萌新在前期的学习中,常用的输入输出函数及其功能~ 跳跃…

ROS2机器人编程简述humble-第二章-Controlling the Iterative Execution .3.1

2.3 ANALYZING THE BR2 BASICS PACKAGE 这一节内容有些多……前一篇:ROS2机器人编程简述humble-第二章-DEVELOPING THE FIRST NODE .2里面只有节点,没有任何实际功能。logger.cpp代码如下所示:#include "rclcpp/rclcpp.hpp"using n…

微信小程序分享的图片被裁切了。怎么让他不裁剪正常比例5:4显示

现在的效果 希望的效果 最主要的是下面的这个函数。把图片转成了5:4的临时图片 cutShareImg(doctorImg:string ){let thatthis;return new Promise((resolve) > {wx.getImageInfo({src: doctorImg, // 这里填写网络图片路径 success: (res) > {var data resconsole.l…

使用 LibreOffice 将 word 转化为 pdf 并解决中文乱码问题

目录 一、安装 LibreOffice 二、解决乱码问题 2.1 查看是否安装中文字体 2.2 准备字体 2.3 导入字体 2.4 验证 项目中有一个在线上传 word 并预览 pdf 报告的需求,因为项目部署在 ubuntu 上面,所以借助libreoffice 实现 word 转 pdf,然…

详细实例说明+典型案例实现 对枚举法进行全面分析 | C++

第五章 枚举法 目录 ●第五章 枚举法 ●前言 1.简要介绍 2.代码及结果示例(简单理解) 3.生活实例 ●二、枚举法的典型案例——鸡兔同笼&质数求解 1.鸡兔同笼 2.质数求解(枚举法) ●总结 前言 简单的来说…

最新 vue-cli 构建项目

vue-cli 构建项目 当前使用最新版本构建一个vue node项目 插件 vue-clivueelement-plusroutervuex 安装vue-cli npm install -g vue-cli安装完后 vue --version 查看版本 vue --version创建一个项目 vue create demo这里要选择版本,不同版本要相组合配置的插件…