利用Wrap Shell Script定位Android Native内存泄漏

简介: ## 前提条件 - Android版本为8.0以上 ## 环境配置 - cd到/src/main目录下,新建shell目录,同时shell目录下配置与libs目录下相同平台的目录,如下app下的层级结构,可看到shell/lib下具有与libs下相同的平台目录结构 ```c ── AndroidManifest.xml ├── java ├── libs │   ├── a

前提条件

  • Android版本为8.0以上

环境配置

  • cd到/src/main目录下,新建shell目录,同时shell目录下配置与libs目录下相同平台的目录,如下app下的层级结构,可看到shell/lib下具有与libs下相同的平台目录结构
── AndroidManifest.xml
├── java
├── libs
│   ├── arm64-v8a
│   └── armeabi-v7a
├── main.iml
├── res
└── shell
    └── lib
        ├── arm64-v8a
        └── armeabi-v7a
  • 分别在shell/lib/目录下建立一个wrap.sh脚本文件,编辑wrap.sh文件并写入如下内容
#!/system/bin/sh
LIBC_DEBUG_MALLOC_OPTIONS=backtrace $@

并赋予脚本其执行权限
chmod +x wrap.sh

注意,如果你最终生成的apk是只需要armeabi-v7a的,则不要在arm64-v8a中放置wrap.sh脚本文件。

  • 打开/build.gradle文件,在sourceSets.main增加资源文件路径,如
sourceSets.main {
        jni.srcDirs = []
        jniLibs.srcDir "src/main/libs"
        resources.srcDir "src/main/shell"
    }
  • 环境配置完成,编译打包apk,使用Android Studio分析apk,确保相应平台里存在wrap.sh脚本文件

获取Native内存分配信息

  • 安装运行apk,并获取pid
  • 对app执行一系列操作,由于此时内存分配时会执行更多的操作,app运行速度可能减慢
  • 终端上执行如下命令,adb shell am dumpheap -n <pid> /data/local/tmp/heap.txt
  • 将/data/local/tmp/heap.txt pull到本地,打开heap.txt可看到一些信息,如下
Android Native Heap Dump v1.0

Total memory: 38937197
Allocation records: 42720
Backtrace size: 16

z 1  sz 20039040  num    1  bt edeff75a edeff654 edeff73e ee44d99a efda71f0 ee4487a4
z 1  sz  3908764  num    1  bt d2a28a38 d2a332b0 d290977a d28f9d96
z 1  sz   520192  num    1  bt cd30ca40 cd2b3ce8 cd2c307a cd2c2e50 cd2c2c24 cd2bca9e ee5cbdac ce546204 ce54d022 ce54f95c ce54ad92 ce53c1b4 ce53c1da ce5dab22 ee2ca8d6 ee29e340
......
  • 下载文件native_heapdump_viewer.py,如果你终端无法直接访问addr2line和objdump两个命令,则需要将python脚本中两命令替换为ndk的路径访问,如
<ndk path>toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-objdump
<ndk path>toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line
  • 使用如下命令对抓到取的native内存分配信息进行符号分析

python native_heapdump_viewer.py --symbols . heap.txt > heapinfo.txt

这时我以获取libQuCore.so库的内存分配信息为例,--symbols是设置给脚本文件路径,注意此时打开heapinfo.txt可能无法获取到正确的地址和文件匹配信息,比如会收到类似如下的信息

/data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so not found for symbol resolution

  2521990   6.72%  92.18%      409       ce5dab22 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so ??? ???
  2520966   6.72%  99.96%      408         ce53c1da /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so ??? ???
  2519574   6.71%  99.94%      381           ce53c1b4 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so ??? ???
  2519574   6.71% 100.00%      381             ce54ad92 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so ??? ???
  2519414   6.71%  99.99%      379               ce54f95c /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so ??? ???
  2517560   6.71%  99.93%      351                 ce54d022 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so ??? ???
  2500576   6.66%  99.33%      160                   ce546204 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so ??? ???

这是因为android需要与手机库路径完全一样的符号文件路径,于是我们在本地新建一个与上述获取到的手机上的相同的路径并将libQuCore.so拷贝到新建的路径下,假设此路径位于symbols目录下,如symbols/data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so路径存在,重新执行上述符号解析命令
python native_heapdump_viewer.py --symbols symbols heap.txt > heapinfo.txt

再次打开heapinfo.txt文件,可以获取libQuCore.so相关的符号与文件、行数匹配的信息了,如下摘取了一部分示例


  2521990   6.72%  92.18%      409       ce5dab22 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so execute_native_thread_routine /Volumes/Android/buildbot/src/android/ndk-r14-release/toolchain/gcc/gcc-4.9/libstdc++-v3/src/c++11/thread.cc:84
  2520966   6.72%  99.96%      408         ce53c1da /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so std::thread::_Impl<std::_Bind_simple<void (*(alivc::ThreadService*))(alivc::ThreadService*)> >::_M_run() /Users/xunshan/Library/Android/sdk/android-ndk-r14b/sources/cxx-stl/gnu-libstdc++/4.9/include/functional:1700 (discriminator 2)
  2519574   6.71%  99.94%      381           ce53c1b4 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so alivc::ThreadWorker(alivc::ThreadService*) /Users/xunshan/Desktop/AliyunSVideo-product/sources/native/modules/alivc_framework/src/mdf/service/thread_service.cpp:18
  2519574   6.71% 100.00%      381             ce54ad92 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so alivc::RenderEngineService::OnInit() /Users/xunshan/Desktop/AliyunSVideo-product/sources/native/modules/alivc_framework/src/render_engine/render_engine_service.cpp:284
  2519414   6.71%  99.99%      379               ce54f95c /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so alivc::Canvas::Init() /Users/xunshan/Desktop/AliyunSVideo-product/sources/native/modules/alivc_framework/src/render_engine/canvas.cpp:36 (discriminator 1)
  2517560   6.71%  99.93%      351                 ce54d022 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so alivc::GraphicContext::Init(void*) /Users/xunshan/Desktop/AliyunSVideo-product/sources/native/modules/alivc_framework/src/render_engine/render_system/GL/graphic_context.cpp:36
  2500576   6.66%  99.33%      160                   ce546204 /data/app/com.aliyun.apsaravideo-e1DYx-Wua0VifW_TwlHhAw==/lib/arm/libQuCore.so alivc::AlivcEGLContext::Init(void*) /Users/xunshan/Desktop/AliyunSVideo-product/sources/native/modules/alivc_framework/src/render_engine/render_system/EGL/egl_context.cpp:59
  • 针对上述获取到的内存分配对应的文件和行数解析的信息,可以分析native的内存分配是否发生了泄漏及哪些地方导致了内存泄漏
目录
相关文章
|
12天前
|
前端开发 Java 编译器
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
70 36
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
|
4月前
|
存储 前端开发 Java
Android MVVM架构模式下如何避免内存泄漏
Android采用MVVM架构开发项目,如何避免内存泄漏风险?怎样避免内存泄漏?
142 1
|
3月前
|
监控 JavaScript 算法
如何使用内存监控工具来定位和解决Node.js应用中的性能问题?
总之,利用内存监控工具结合代码分析和业务理解,能够逐步定位和解决 Node.js 应用中的性能问题,提高应用的运行效率和稳定性。需要耐心和细致地进行排查和优化,不断提升应用的性能表现。
220 77
|
7月前
|
存储 设计模式 监控
运用Unity Profiler定位内存泄漏并实施对象池管理优化内存使用
【7月更文第10天】在Unity游戏开发中,内存管理是至关重要的一个环节。内存泄漏不仅会导致游戏运行缓慢、卡顿,严重时甚至会引发崩溃。Unity Profiler作为一个强大的性能分析工具,能够帮助开发者深入理解应用程序的内存使用情况,从而定位并解决内存泄漏问题。同时,通过实施对象池管理策略,可以显著优化内存使用,提高游戏性能。本文将结合代码示例,详细介绍如何利用Unity Profiler定位内存泄漏,并实施对象池来优化内存使用。
504 0
|
4月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
84 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
5月前
|
Java 测试技术 Android开发
Android性能测试——发现和定位内存泄露和卡顿
本文详细介绍了Android应用性能测试中的内存泄漏与卡顿问题及其解决方案。首先,文章描述了使用MAT工具定位内存泄漏的具体步骤,并通过实例展示了如何分析Histogram图表和Dominator Tree。接着,针对卡顿问题,文章探讨了其产生原因,并提供了多种测试方法,包括GPU呈现模式分析、FPS Meter软件测试、绘制圆点计数法及Android Studio自带的GPU监控功能。最后,文章给出了排查卡顿问题的四个方向,帮助开发者优化应用性能。
318 4
Android性能测试——发现和定位内存泄露和卡顿
|
4月前
|
设计模式 Java Android开发
安卓应用开发中的内存泄漏检测与修复
【9月更文挑战第30天】在安卓应用开发过程中,内存泄漏是一个常见而又棘手的问题。它不仅会导致应用运行缓慢,还可能引发应用崩溃,严重影响用户体验。本文将深入探讨如何检测和修复内存泄漏,以提升应用性能和稳定性。我们将通过一个具体的代码示例,展示如何使用Android Studio的Memory Profiler工具来定位内存泄漏,并介绍几种常见的内存泄漏场景及其解决方案。无论你是初学者还是有经验的开发者,这篇文章都将为你提供实用的技巧和方法,帮助你打造更优质的安卓应用。
|
5月前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
116 0
|
7月前
|
消息中间件 Android开发 开发者
🔍深度剖析Android内存泄漏,让你的App远离崩溃边缘,稳如老狗!🐶
【7月更文挑战第28天】在 Android 开发中,内存管理至关重要。内存泄漏可悄无声息地累积,最终导致应用崩溃或性能下滑。它通常由不正确地持有 Activity 或 Fragment 的引用引起。常见原因包括静态变量持有组件引用、非静态内部类误用、Handler 使用不当、资源未关闭及集合对象未清理。使用 Android Studio Profiler 和 LeakCanary 可检测泄漏,修复方法涉及使用弱引用、改用静态内部类、妥善管理 Handler 和及时释放资源。良好的内存管理是保证应用稳定性的基石。
144 4
|
6月前
|
搜索推荐 Java API
Electron V8排查问题之分析 node-memwatch 提供的堆内存差异信息来定位内存泄漏对象如何解决
Electron V8排查问题之分析 node-memwatch 提供的堆内存差异信息来定位内存泄漏对象如何解决
181 0

热门文章

最新文章

  • 1
    解决 Ubuntu 用户登录后的 shell 和功能问题
  • 2
    Python执行Shell命令并获取结果:深入解析与实战
  • 3
    【linux】Shell脚本中basename和dirname的详细用法教程
  • 4
    [oeasy]python064_命令行工作流的总结_vim_shell_python
  • 5
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 6
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 8
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 9
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 10
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex