精华内容
下载资源
问答
  • android内存分析
    千次阅读
    2021-12-17 21:22:57

    在内存分析的时候,我们都会用Android studio自带的Profiler工具,很好用,可以用图形直观的展示。其实这些数据是通过dumpsys命令从手机中取回来的,然后将其绘制出来而已。其实关键还是理解dumpsys能取到的数据是什么含义。

    • 私有(干净和脏)RAM
      这是仅由您的进程使用的内存。这是您的应用进程销毁后系统可以回收的 RAM 容量。通常情况下,最重要的部分是私有脏 RAM,它的开销最大,因为只有您的进程使用它,而且其内容仅存在于 RAM 中,所以无法通过分页机制映射到硬盘(因为 Android 不使用交换)。您进行的所有 Dalvik 和原生堆分配都将是私有脏 RAM;您与 Zygote 进程共享的 Dalvik 和原生分配则是共享脏 RAM。
    • 实际使用的物理内存(比例分配共享库占用的内存,PSS)
      这是对应用 RAM 占用情况的衡量,考虑了在进程之间共享 RAM 页的情况。您的进程独占的 RAM 页会直接计入其 PSS 值,而与其他进程共享的 RAM 页则仅会按相应比例计入 PSS 值。例如,两个进程之间共享的 RAM 页会将其一半的大小分别计入这两个进程的 PSS 中。

    上面是两个很重要的概念,是实际中,我们关系pss就可以,这个可以理解成app实际使用的内存,而且,Android profiler绘制使用的也是这些数据。
    其实,我们拿到这些数据也是可以自己绘制的,比如,我们在用appium在做自动化测试的时候,整个流程中就需要实时绘制出内存的变化。

    这部分知识的深入了解,可以看参考中的几篇文章。

    参考

    内存测试——查看全面的内存分配
    Android 游戏 四种内存评估方式
    官方解释

    更多相关内容
  • android 内存分析

    2016-10-29 09:33:21
    Android内存分析
  • 主要从5个模块入手: 1 java的GC机制以及Android最大堆内存分配 2 Monitors 3 DDMS/Traceview 4 Mat 5 LeakCanary 6 开发中要注意的点。
  • 一、前言我们知道,Android系统检测到app有不再使用对象时,就会进行内存回收相关的工作。尽管Android检测无用对象、回收内存的方法在不断改进,但在目前所有的Android版本中,进行上述工作时,系统仍需要短暂地停止...

    一、前言

    我们知道,Android系统检测到app有不再使用对象时,就会进行内存回收相关的工作。

    尽管Android检测无用对象、回收内存的方法在不断改进,

    但在目前所有的Android版本中,进行上述工作时,系统仍需要短暂地停止app的运行。

    在大多数情况下,系统进行内存回收的行为是无法被用户察觉到的。

    然而,如果应用分配内存的速度大于系统回收的速度,

    那么app进程的正常运行可能就回受到影响。

    毕竟,系统必须回收到足够的供app需要的内存,才会恢复处于暂停状态的app。

    在这种情况下,app就可能出现掉帧、卡顿等现象。

    在更严重的情况下,如果出现了内存泄露的问题,那么系统中就可能堆积无法释放的内存,

    使得系统必须更加频繁地进行内存回收,从而降低系统的性能。

    甚至在极端条件下,系统不得不杀死部分正在后台运行的app进程。

    于是用户将后台应用移到前台时,却发现应用无故重启,这显然带来了较差的用户体验。

    由此可见,内存对于app而言,是极其关键的性能指标。

    目前,分析app内存的工具有很多,

    本文主要记录一下Android Studio内置的内存分析工具Memory Profiler。

    二、基本介绍

    Memory Profiler是Android Profiler的一个组件, 用于帮助分析内存泄露和内存抖动的问题。

    当PC连接Android L以上的设备时,该工具才能够正常使用。

    Memory Profiler的功能包括:

    展示应用内存使用情况的实时图像、抓取内存的dump信息、强制垃圾回收及追踪内存分配。

    2.1 开启步骤

    打开Memory Profiler的步骤为:

    1、 依次点击Android Studio的View → Tool Windows → Android Profiler,

    或直接点击工具栏Android Profiler对应的图标;

    2、 PC连接Android终端后,在Android Profiler对应的区域选择接的设备和需要监控的进程:

    894d021342e2

    3、 点击Android Profiler界面中MEMORY区域的任意位置,即可开启Memory Profiler,如下图所示:

    894d021342e2

    需要注意的是,如果PC连接Android 7.1以下的设备时,有些关键数据可能无法被Android Profiler统计,

    此时Android Profiler会显示如下信息:

    894d021342e2

    这时我们需要依次点击Android Studio的Run → Edit Configurations → Profiling 按键,选中app后点击Enabled advanced profiling,

    如下图所示:

    894d021342e2

    为了支持该功能,要求app对应的gradle版本必须在2.4以上。

    2.2 界面介绍

    打开Memory Profiler后,主界面如下所示(为了方便,这里直接盗取Android技术文档中的图):

    894d021342e2

    其中:

    标注1对应的按键用于强制内存回收。

    标注2对应的按键用于抓取进程内存的dump信息。

    标注3对应的按键用于记录内存的分配信息(连接Android 7.1及以下才会有此按键)。

    初次点击时,对应统计的开始时间点;再次点击时,对应统计的结束时间点。

    进程在两个时间点之间的内存分配信息,将被Memory Profiler记录和分析。

    标注4对应的区域用于缩放时间轴。

    标注5对应的按键用于显示实时的内存数据。

    标注6对应的区域用于记录事件发生的时间点及大致持续的时间(例如activity状态改变、用户操作界面等事件)。

    标注7对应的区域用于显示内存使用情况对应的时间轴(与标注6结合,就可以看出各事件带来的内存变化情况)。

    需要说明的是,标注7对应区域显示的内容包括:

    不同类型内存占用情况对应的图像;

    分配对象数量对应的短画线;

    内存回收事件发生的时机。

    2.3 统计的数据类型及含义

    Memory Profiler主要根据Android系统提供的信息,

    统计app独自占用内存,即不统计app与系统或其它app共有的内存。

    Memory Profiler统计内存的种类如下图所示:

    894d021342e2

    如上图所示,其中:

    Java表示Java代码或Kotlin代码分配的内存;

    Native表示C或C++代码分配的内存(即使App没有native层,调用framework代码时,也有可能触发分配native内存);

    Graphics表示图像相关缓存队列占用的内存;

    Stack表示native和java占用的栈内存;

    Code表示代码、资源文件、库文件等占用的内存;

    Others表示无法明确分类的内存;

    Allocated表示Java或Kotlin分配对象的数量(Android8.0以下时,仅统计Memory Profiler启动后,进程再分配的对象数量;

    8.0以上时,由于系统内置了统计工具,Memory Profiler可以得到整个app启动后分配对象的数量)。

    三、基本用法

    对Memory Profiler有了基本的了解后,我们来看看它的基本用法。

    3.1 查看内存分配情况

    Memory Profiler可以查看两个时间点之间的内存分配情况,包括:

    对象的类型、占用内存的大小、栈信息等。

    连接8.0以上的设备时,Memory Profiler还可以显示对象被回收的时间。

    PC连接8.0以上的设备时,在内存统计的时间线上,直接点击和拖动就可以选择观察区域;

    连接低版本的设备时,则需要点击Record Memory allocations按键(2.2小结介绍的标注3)选择观察区域。

    选定观察区域后, Memory Profiler就可以统计这段时间内app分配内存的情况:

    894d021342e2

    从图中可以看出,Memory Profiler可以显示分配对象的类名;

    点击类后,会在Instance View显示具体的对象;

    点击具体对象后,会在Call back区域显示调用栈。

    点击调用栈信息后,就会跳转到具体的代码。

    3.2 查看内存占用情况

    点击2.2小结介绍的标注2,即可抓取点击后一段时间内app占用内存的dump信息。

    通过dump信息,我们可以看到app当前仍存在于内存中的对象。

    结合代码,我们可以分析是否有本应被析构却仍存活的泄露对象。

    与统计内存分配信息一样,内存占用信息同样会显示对象的类型、数量、占用内存的大小、引用关系等。

    如下图所示:

    894d021342e2

    图中Alloc Count表示堆中分配对象的数量;

    Shallow Size表示对象使用Java内存的大小,单位为byte;

    Retained Size表示对象占用的实际内存大小,大于等于Shallow Size;

    7.0及以上版本的设备,还会显示对象占用的Native Size。

    点击具体的对象时,也会显示Instance View。

    此时,Instance View显示的信息变多了,包括:

    Depth表示当前对象到任一GC root的最短跳数;

    Shallow Size、Retained Size的含义与前文一致。

    同样,7.0及以上版本的设备,还会显示对象占用的Native Size。

    从图中可以看出,Instance View不会显示栈信息。

    如果想获得栈信息的话,必须先点击Record Memory allocations按键。

    四、使用示例

    利用Memory Profiler,我分析了一下某反病毒引擎SDK的内存占用情况。

    随便写了个demo,继承SDK后启动app,内存占用情况如下图所示:

    894d021342e2

    然后,通过操作UI初始化SDK,发现稳定后内存占用情况如下图所示:

    894d021342e2

    比对前后两图,不考虑界面UI变化消耗的内存,

    可以看出:内存增加的主体部分来自于Native函数,其它类型的内存变化几乎可以忽略。

    这是因为该SDK初始化时,最主要的工作是在Native层加载底层的so文件。

    接下来,我们在demo里调用SDK的接口,批量扫描样本,统计内存消耗情况如下图所示:

    894d021342e2

    从图中可以看出app消耗的内存飙升到了104M,

    与初始化后的内存相比,其中增加主要是code和native类型的内存。

    根据2.3小结的描述,我们知道code类型统计的是app进程需要的资源文件、库文件等,

    因此这部分内存主要是SDK中引擎加载病毒库等消耗掉的内存;

    而Native内存的消耗,应该也是由于引擎扫描文件导致的。

    按照3.1小结的描述,我们查看了一下批量扫描这段时间内,

    app进程内存分配的情况,如下图所示:

    894d021342e2

    容易看出,在这段时间内,除去native内存外,整个app分配内存并不大,

    且按照对象占用内存的大小排序,排在前列的都是基本数据类型。

    因此,这段时间内app进程的内存应该是比较正常的。

    我们进行GC操作,内存情况如下图所示:

    894d021342e2

    发现内存几乎和扫描前一致,按照3.2小结进行dump分析,没有发现泄露对象。

    因此,可以确认SDK不存在内存泄露的问题(dump信息含有sdk的隐私,这里就不再附图了)。

    五、总结

    至此,我们已经介绍了Android Memory Profiler工具的基本情况,

    并简单列举了该工具的使用方式。

    个人感觉,不同于LeakCanary,

    Android Memory Profiler更侧重于宏观场景下的内存分析。

    ————————————————

    版权声明:本文为CSDN博主「ZhangJianIsAStark」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/gaugamela/article/details/79027538

    展开全文
  • 内存泄露是Android开发中常见的性能问题。本文作者以真实案例演示内存泄露从发现、分析定位到最终解决的全过程。一款优秀的Android应用,不仅要有完善的功能,也要有良好的体验,而性能是影响体验的一个重要因素。...
  • 一、Android内存机制 Android的程序由Java语言编写,所以Android内存管理与Java的内存管理相似。程序员通过new为对象分配内存,所有对象在java堆内分配空间;然而对象的释放是由垃圾回收器来完成的。C/C++中的...
  • Android内存泄漏终极解决篇(上)中我们介绍了如何检查一个App是否存在内存泄漏的问题,本篇将总结典型的内存泄漏的代码,并给出对应的解决方案。内存泄漏的主要问题可以分为以下几种类型: 静态变量引起的内存...
  • Android 内存分析工具.pdf
  • 内存溢出(Out Of Memory):Android系统中每一个应用程序可以向系统申请一定的内存,当申请的内存不够用的时候,就产生了内存溢出。 内存泄漏:当某个对象不再被使用,即不再有变量引用它时,该对象占用的内存就会...
  • Android内存解析

    千次阅读 2019-02-21 08:38:42
    内存 冷启动 冷启动:在启动应用前,系统没有该应用的任何进程信息 热启动:用户使用返回键退出应用,然后马上有重新启动应用 流程 冷启动时间:从应用启动(创建进程),到完成视图的第一次绘制(即Activiy内容对...

    内存

    冷启动

    冷启动:在启动应用前,系统没有该应用的任何进程信息
    热启动:用户使用返回键退出应用,然后马上有重新启动应用

    流程

    冷启动时间:从应用启动(创建进程),到完成视图的第一次绘制(即Activiy内容对用户可见)
    过程:Zygote进程中fork创建出一个新的进程,然后创建和初始化Application类,创建MainActivity类,inflate布局,当onCreate/onStart/onResum()都走完,contentView的measure/layout/draw显示在界面上。
    流程:Application构造器–>attachBaseContext()–>OnCreate()–>Activity构造器–>onCreate–>配置主题背景等属性–>onStart()–>onResume–>测量布局绘制显示在界面上

    冷启动时间优化

    ​ 1、减少onCreate方法的工作量
    ​ 2、不要让Application参与业务逻辑
    ​ 3、不要在Application中做耗时操作
    ​ 4、不要以静态变量方式在Application中保存数据
    ​ 5、布局优化/mainThread尽量延迟初始化

    Java内存分配策略

    静态存储区(方法区)
    ​ 所有线程共享。包含所有的class和static变量。包含的都是在整个程序中永远唯一的元素,如class,static变量
    栈区
    ​ 每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(对象都存放在堆区中)
    ​ 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问
    ​ 栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)
    堆区
    ​ 动态内存分配,new出来的对象都存放在此区域,没用的对象都会被GC进行回收
    ​ 存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
    ​ jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身

    Java内存管理

    分配
    ​ 程序完成,通过关键字new为每个对象申请内存空间 (基本类型除外),所有的对象都在堆 (Heap)中分配空间
    释放
    ​ 对象的释放是由垃圾回收机制决定和执行的。减轻开发者负担的同时,也加重了JVM的工作。因为,GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控

    内存管理机制特点

    1、更少的占用内存
    2、在合适的时候合理释放系统资源
    3、在系统内存紧张的情况下,能释放大部分不重要的资源,来为Android系统提供可用内存
    4、能够合理的在特殊生命周期中保存或还原重要的数据,以至于能够正确的重新恢复该应用

    内存优化方法

    1、Service完成任务后,尽量停止它
    2、在UI不可见的时候,释放一些只有UI使用的资源
    3、在系统内存紧张的时候尽量能够多的释放掉一些非重要的资源
    4、避免滥用Bitmap导致的内存泄漏问题
    5、使用针对内存优化过的容器
    6、避免使用依赖注入框架
    7、使用ZIP对齐的apk
    8、使用多进程

    其他优化

    Sharepreference相关
    ​ 不能跨进程同步
    ​ 在存储Sharepreference的文件过大问题
    内存对象序列化
    ​ 将对象的状态信息转换为可以存储或者传输形式的过程
    ​ 两种方式:Serializable(Java),Parcelable(Android),前者性能低,因其序列化时产生大量的临时变量,引起频繁GC;后者不能将数据存储在磁盘上

    内存泄漏

    ​ 指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果

    ​ 该被释放的对象(可达,无用)没有被释放,一直被某个或者某些实例引用所持有,导致不能被GC回收

    集合类泄漏

    ​ 包含全局性变量,如类中的静态属性,全局性的map等

    静态成员变量导致的内存泄露

    //将Context作为静态成员变量使用
    private static Context mContext;
    

    单例造成的内存泄漏

    ​ 传入的上下文非ApplicationContext

    ​ 正确做法:使用ApplicationContext;ActivityContext或ServiceContext软引用

    匿名内部类/非静态内部类和异步线程

    ​ Handler、Runnable和AsyncTask。其持有外部类引用,外部类回收时,内部类

    ​ Handler 发送的 Message 尚未被处理,则该 Message 及发送它的 Handler 对象将被线程 MessageQueue 一直持有

    ​ 正确做法:静态内部类 + WeakReference 这种方式

    ​ onDestroy中用Handler.removeAllCallbackAndMessage

    ​ 案例:Volley在Activity中使用,Response回调Listener采用静态内部类和WeakReference使用Activity

    资源未关闭造成的内存泄漏

    ​ IO流,Cursor、File、Socket

    注册对象未反注册

    ​ 广播,service

    总结

    尽量避免使用 static 成员变量

    避免 override finalize()

    不需要的对象,赋值为null

    持久化Drawable,定义成static

    检测

    DDMS Heap

    Heap Tool进行内存快照前后对比

    MAT插件打开.hprof具体定位内存泄露

    AndroidStudio的Allocation Tracker

    LeakCanary

    UI卡顿

    原理

    ​ Android系统每隔16ms都会对界面进行渲染一次,造成卡顿的原因就是Android系统在渲染的时候丢帧了,16ms = 1000/60hz,相当于60fps(每秒帧率)

    过度绘制(overdraw)

    屏幕上的某个项目在同一帧内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域内绘制了 多次,这就浪费了大量的CPU以及GPU资源
    查看显示GPU过度绘制显示情况:设置-> 开发者选项->调试GPU过度绘制->显示GPU过度绘制,绘制倍数依次为蓝色,绿色,淡红,深红。每次增加一倍绘制

    UI卡顿原因

    1、在UI线程中做轻微耗时操作
    2、布局Layout过于复杂,无法在16ms内完成渲染
    3、同一时间动画执行次数过多
    4、View过度绘制或频繁的触发measure,layout,导致measure,layout累计耗时过多以及整个View频繁的重新渲染
    5、内存频繁触发GC过多,导致暂时阻塞渲染操作
    6、冗余资源以及逻辑等导致加载或执行缓慢

    解决方法

    1、布局优化
    ​ 尽量不存在布局冗余嵌套以及过于复杂的布局。如果有重用的布局使用include标签
    2、列表及Adapter优化
    ​ 使用View的重用机制。在列表滑动的时候,不要去加载资源,显示默认的资源或者图片的缩略图,在列表滑动结束的时候再加载
    3、背景和图片等内存分配的优化
    ​ 尽量减少一些背景中不必要的设置,背景图片尽量进行压缩处理。
    4、避免ANR
    ​ 在主线程(UI线程)不要进行耗时操作

    展开全文
  • Android 内存分析工具 : Memory Profiler

    千次阅读 2022-02-16 18:39:32
    我们知道,Android系统检测到app有不再使用对象时,就会进行内存回收相关的工作。 尽管Android检测无用对象、回收内存的方法在不断改进, 但在目前所有的Android版本中,进行上述工作时,系统仍需要短暂地停止app的...

    一、前言

     
    我们知道,Android系统检测到app有不再使用对象时,就会进行内存回收相关的工作。

    尽管Android检测无用对象、回收内存的方法在不断改进, 
    但在目前所有的Android版本中,进行上述工作时,系统仍需要短暂地停止app的运行。

    在大多数情况下,系统进行内存回收的行为是无法被用户察觉到的。 
    然而,如果应用分配内存的速度大于系统回收的速度, 
    那么app进程的正常运行可能就回受到影响。

    毕竟,系统必须回收到足够的供app需要的内存,才会恢复处于暂停状态的app。 
    在这种情况下,app就可能出现掉帧、卡顿等现象。

    在更严重的情况下,如果出现了内存泄露的问题,那么系统中就可能堆积无法释放的内存, 
    使得系统必须更加频繁地进行内存回收,从而降低系统的性能。

    甚至在极端条件下,系统不得不杀死部分正在后台运行的app进程。 
    于是用户将后台应用移到前台时,却发现应用无故重启,这显然带来了较差的用户体验。

    由此可见,内存对于app而言,是极其关键的性能指标。 
    目前,分析app内存的工具有很多, 
    本文主要记录一下Android Studio内置的内存分析工具Memory Profiler。
     

    二、基本介绍 


    Memory Profiler是Android Profiler的一个组件, 用于帮助分析内存泄露和内存抖动的问题。 
    当PC连接Android L以上的设备时,该工具才能够正常使用。

    Memory Profiler的功能包括: 
    展示应用内存使用情况的实时图像、抓取内存的dump信息、强制垃圾回收及追踪内存分配。

    2.1 开启步骤 
    打开Memory Profiler的步骤为: 
    1、 依次点击Android Studio的View → Tool Windows → Android Profiler, 
    或直接点击工具栏Android Profiler对应的图标;

    2、 PC连接Android终端后,在Android Profiler对应的区域选择接的设备和需要监控的进程:

     

     3、 点击Android Profiler界面中MEMORY区域的任意位置,即可开启Memory Profiler,如下图所示: 

     

     需要注意的是,如果PC连接Android 7.1以下的设备时,有些关键数据可能无法被Android Profiler统计, 
    此时Android Profiler会显示如下信息: 

     

     这时我们需要依次点击Android Studio的Run → Edit Configurations → Profiling 按键,选中app后点击Enabled advanced profiling, 
    如下图所示: 

     为了支持该功能,要求app对应的gradle版本必须在2.4以上。

    2.2 界面介绍 
    打开Memory Profiler后,主界面如下所示(为了方便,这里直接盗取Android技术文档中的图): 

     

     

    其中: 
    标注1对应的按键用于强制内存回收。

    标注2对应的按键用于抓取进程内存的dump信息。

    标注3对应的按键用于记录内存的分配信息(连接Android 7.1及以下才会有此按键)。 
    初次点击时,对应统计的开始时间点;再次点击时,对应统计的结束时间点。 
    进程在两个时间点之间的内存分配信息,将被Memory Profiler记录和分析。

    标注4对应的区域用于缩放时间轴。

    标注5对应的按键用于显示实时的内存数据。

    标注6对应的区域用于记录事件发生的时间点及大致持续的时间(例如activity状态改变、用户操作界面等事件)。

    标注7对应的区域用于显示内存使用情况对应的时间轴(与标注6结合,就可以看出各事件带来的内存变化情况)。 
    需要说明的是,标注7对应区域显示的内容包括: 
    不同类型内存占用情况对应的图像; 
    分配对象数量对应的短画线; 
    内存回收事件发生的时机。
     

    2.3 统计的数据类型及含义 
    Memory Profiler主要根据Android系统提供的信息, 
    统计app独自占用内存,即不统计app与系统或其它app共有的内存。

    Memory Profiler统计内存的种类如下图所示: 

     

    如上图所示,其中: 
    Java表示Java代码或Kotlin代码分配的内存;

    Native表示C或C++代码分配的内存(即使App没有native层,调用framework代码时,也有可能触发分配native内存);

    Graphics表示图像相关缓存队列占用的内存;

    Stack表示native和java占用的栈内存;

    Code表示代码、资源文件、库文件等占用的内存;

    Others表示无法明确分类的内存;

    Allocated表示Java或Kotlin分配对象的数量(Android8.0以下时,仅统计Memory Profiler启动后,进程再分配的对象数量; 
    8.0以上时,由于系统内置了统计工具,Memory Profiler可以得到整个app启动后分配对象的数量)。
     

    三、基本用法

     
    对Memory Profiler有了基本的了解后,我们来看看它的基本用法。

    3.1 查看内存分配情况 
    Memory Profiler可以查看两个时间点之间的内存分配情况,包括: 
    对象的类型、占用内存的大小、栈信息等。 
    连接8.0以上的设备时,Memory Profiler还可以显示对象被回收的时间。

    PC连接8.0以上的设备时,在内存统计的时间线上,直接点击和拖动就可以选择观察区域; 
    连接低版本的设备时,则需要点击Record Memory allocations按键(2.2小结介绍的标注3)选择观察区域。

    选定观察区域后, Memory Profiler就可以统计这段时间内app分配内存的情况: 
     

     从图中可以看出,Memory Profiler可以显示分配对象的类名; 
    点击类后,会在Instance View显示具体的对象; 
    点击具体对象后,会在Call back区域显示调用栈。 
    点击调用栈信息后,就会跳转到具体的代码。

    3.2 查看内存占用情况 
    点击2.2小结介绍的标注2,即可抓取点击后一段时间内app占用内存的dump信息。

    通过dump信息,我们可以看到app当前仍存在于内存中的对象。 
    结合代码,我们可以分析是否有本应被析构却仍存活的泄露对象。

    与统计内存分配信息一样,内存占用信息同样会显示对象的类型、数量、占用内存的大小、引用关系等。 
    如下图所示: 
     

     

     

    图中Alloc Count表示堆中分配对象的数量; 
    Shallow Size表示对象使用Java内存的大小,单位为byte; 
    Retained Size表示对象占用的实际内存大小,大于等于Shallow Size; 
    7.0及以上版本的设备,还会显示对象占用的Native Size。

    点击具体的对象时,也会显示Instance View。 
    此时,Instance View显示的信息变多了,包括: 
    Depth表示当前对象到任一GC root的最短跳数; 
    Shallow Size、Retained Size的含义与前文一致。 
    同样,7.0及以上版本的设备,还会显示对象占用的Native Size。

    从图中可以看出,Instance View不会显示栈信息。 
    如果想获得栈信息的话,必须先点击Record Memory allocations按键。

    四、使用示例 


    利用Memory Profiler,我分析了一下某反病毒引擎SDK的内存占用情况。 
    随便写了个demo,继承SDK后启动app,内存占用情况如下图所示: 
     

     然后,通过操作UI初始化SDK,发现稳定后内存占用情况如下图所示: 

     

     

     

    比对前后两图,不考虑界面UI变化消耗的内存, 
    可以看出:内存增加的主体部分来自于Native函数,其它类型的内存变化几乎可以忽略。 
    这是因为该SDK初始化时,最主要的工作是在Native层加载底层的so文件。

    接下来,我们在demo里调用SDK的接口,批量扫描样本,统计内存消耗情况如下图所示: 
     

     

     

    从图中可以看出app消耗的内存飙升到了104M, 
    与初始化后的内存相比,其中增加主要是code和native类型的内存。

    根据2.3小结的描述,我们知道code类型统计的是app进程需要的资源文件、库文件等, 
    因此这部分内存主要是SDK中引擎加载病毒库等消耗掉的内存; 
    而Native内存的消耗,应该也是由于引擎扫描文件导致的。

    按照3.1小结的描述,我们查看了一下批量扫描这段时间内, 
    app进程内存分配的情况,如下图所示: 

     

    容易看出,在这段时间内,除去native内存外,整个app分配内存并不大, 
    且按照对象占用内存的大小排序,排在前列的都是基本数据类型。 
    因此,这段时间内app进程的内存应该是比较正常的。

    我们进行GC操作,内存情况如下图所示: 

     

    发现内存几乎和扫描前一致,按照3.2小结进行dump分析,没有发现泄露对象。 
    因此,可以确认SDK不存在内存泄露的问题(dump信息含有sdk的隐私,这里就不再附图了)。

    五、总结 


    至此,我们已经介绍了Android Memory Profiler工具的基本情况, 
    并简单列举了该工具的使用方式。

    个人感觉,不同于LeakCanary, 
    Android Memory Profiler更侧重于宏观场景下的内存分析。

    文章转载:

    Android内存分析工具:Memory Profiler

     

     

    展开全文
  • android应用开发的总结,GC内存回收的原来和算法,JVM内存管理的方式
  • Android Studio内存泄漏分析工具汇总时间:2017-04-25来源:Android开发...今天就和大家分享下Android Studio中常用的内存泄漏分析工具,希望对大家快速分析和定位Android内存泄漏有所帮助。1.Android MonitorAndro...
  • Android内存分析之procrank命令

    万次阅读 2019-03-04 13:45:21
    procrank是/system/xbin/下的一个命令,在整机开发的时候,使用该命令查看应用进程的内存情况很方便。但是这个命令正常在debug/eng模式编译的时候才有,如果你是做第三方应用开发,如果可以root的手机的话,通过往该...
  • Android设备内存动不动就上G的情况下,的确没有必要去太在意APP对Android系统内存的消耗,但在实际工作中我做的是教育类的小学APP,APP中的按钮、背景、动画变换基本上全是图片,在2K屏上(分辨率2048*1536)一张...
  • 导读:C++内存泄漏问题的分析、定位一直是Android平台上困扰开发人员的难题。因为地图渲染、导航等核心功能对性能要求很高,高德地图APP中存在大量的C++代码。解决这个问题对于产品质量尤为重要和关键,高德地图技术...
  • Android内存监控与分析(三):内存分析及原理APP测试中难免会有各种显式或者隐式的内存泄漏(Memory Leak)问题,如果不及时发现处理,可能会因为内存泄漏导致各种奇怪的问题(如,卡顿和闪退),甚至可能出现因...
  • 1、内存了解在Android App的性能优化的各个部分里,内存方面的知识较多且不易理解,内存的问题绝对是最令人头疼的一部分,需要对内存基础知识、内存分配、内存管理机制等非常熟悉,才能排查问题。1.1 了解进程的地址...
  • Android的开发中,经常听到“内存泄漏”这个词。“内存泄漏”就是一个对象已经不需要再使用了,但是因为其它的对象持有该对象的引用,导致它的内存不能被回收。“内存泄漏”的慢慢积累,最终会导致OOM的发生,千里...
  • 美团点评⾼级⼯程师张毅然在GMTC2017全球移动技术大会上做了主题为《Android内存泄漏自动化链路分析组件Probe》的分享,就业内解决⽅案,问题和策略和案例分析进行了深入的分享
  • 所以,唯一能够解决问题的办法,就是尝试去分析应用程序的内存使用情况,那么本篇文章就会教大家如何进行分析。如果你还没有看过前面一篇文章,建议先去阅读虽说现在的手机内存都已经非常大了,但是我们大家都知道,...
  • 本周公司项目解决内存泄漏,使用Android studio profiler工具进行分析。 在人工monkey测试点击管理页面各项菜单后,工具内存查看页面看到内存有增长不是释放的情况。但是dump后未发现哪个页面 或明确的对象没有释放...
  • Android--内存泄露分析

    千次阅读 2021-11-09 20:36:31
    java中的内存泄露是指一个无用对象持续占有内存或无用对象的内存得不到及时的释放,从而造成的内存控件的浪费称为内存泄露。 强引用(StrongReference):JVM 宁可抛出 OOM ,也不会让 GC 回收具有强引用的对象; 软...
  • 下面这张图就展示了Android内存的回收管理策略(图来自Google2011的IO大会)图中的每个圆节点代表对象的内存资源,箭头代表可达路径。当圆节点与GCRoots存在可达路径时,表示当前资源正被引用,虚拟机是无法对其进行...
  • 这里就有疑问了,Android系统有自己的垃圾回收机制,可以不定期的回收掉不使用的内存空间,当然也包括Bitmap的空间。那为什么还需要这个方法呢? Bitmap类的构造方法都是私有的,所以开发者不能直接new出一个Bitmap...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 170,626
精华内容 68,250
关键字:

android内存分析