内容简介
1.问题描述
2.寻找原因
3.Android Studio 监视器

1.问题简述
最近几个月,我们公司的 Android app 进行了一次 UI(User Interface,用户界面)的大更新,新的用户界面比原先的高大上很多。
新界面的设计和素材制作外包给一家法国比较有名的设计公司。
开发这边要把美工设计的图片和界面应用到 Android 代码中。这部分主要是我来做,另一个同事也负责一部分。
现在新 UI 界面已经更新完毕,不过最近测试组发现了一个问题:在 Samsung Galaxy S5 上,app 在打了好几通加密电话后会崩溃。而在其他设备如 Samsung Galaxy A56,Samsung Galaxy S7 / S7 Edge 上则没见崩溃。

2.寻找原因
这个问题可是非常严重, app 直接崩溃是非常影响用户体验的。因此组长很重视这个问题,拜托我尽快解决。
首先,我通过 adb 查看了一下 Logcat 输出的 Log (日志),很快发现了原来是内存使用过多,超出了承受范围。可以看到日志中有 「Out of memory」(内存用尽了) 的字段。
那么究竟是哪个部分使用了过多的内存呢?就得一点点「寻根究底」了。

3.studio监控
Android Studio 绝对是目前开发 Android 的必备工具,因为是 Google 自己家的,所以功能强大,更新频繁。
如果你「不幸」还在用 Eclipse 这样的 Google 不再支持 Android 更新的软件来开发 Android,那我只能对你表示「同情」。
Android Studio 的下载地址,需要「番茄」:https://developer.android.com/studio/index.html
国内的朋友可以去这里,不需要「番茄」:http://www.android-studio.org/
开启 Android Studio 后,在左下方的栏目中可以看到 Android Monitor 这个菜单,点击之后会显示 Logcat 或 Monitors 的界面。
Logcat 就是显示日志的,而 Monitors 中是监视系统的各项数据。
monitor 是英语「监视器」的意思。我们切到 Monitors 那一栏,可以看到有四项数据,分别是 Memory (内存),CPU (中央处理器),Network (网络),GPU (图形处理器)。

如下图所示:

上图中我最关心的当然是 Memory 那一项了,因为我可以选择追踪连接了的哪个设备中的哪一个组件的内存使用情况。
比如上图中,我们选择的是 Samsung SM-G900F Android 4.4.2 API 19 这一个设备。

Samsung SM-G900F 是 Samsung S5 的型号。
Android 4.4.2 表示设备上安装的 Android 版本是 4.4.2。
API 19 表示 Android 的 API 版本是 19。

而被我用白色长条挡住的就是我们公司的产品的那个组件的名称。这样我就可以只监视某一个组件的内存使用了。
可以看到目前的内存使用是 15.89 MB。挺少的,因为我目前位于产品的 Portal(入口,门户)界面,还没进入任何一个子界面。
此时,我点击 Portal 界面上的 Voice 图标,进入 Voice(语音)子界面。 因为我们拨打加密电话就是在 Voice 子界面中进行。
进入 Voice 子界面后,可以看到内存使用如下图所示,迅速蹿高:

可以看到内存使用从原先的 15.89 MB 一下子攀升到 94.71 MB。苍了天了 …
那究竟是 Voice 子界面中的哪个部分消耗了这么多内存呢?
Voice 子界面是一个 Activity,它有三个 Fragment,是配合 ViewPager 来实现 Fragment 之间的切换。这三个 Fragment 分别是 History,Contacts,Dialer,从左到右排列。

结构是类似下图这样的:

由于公司产品的保密性,我不能放出任何截图。

History 是通话的历史记录,是一个 ListView。
Contacts 是同一个或不同服务器上的其他用户,也是一个 ListView。
Dialer 是一个拨号界面,比较复杂,一共有三块内容,最上面是显示号码的区域,带有删除的键;中间一大块是键盘(0 到 9 这 十个数字键,再加 # 键和 + 键。一共 12 个按键);最下面是一个拨打加密电话的按钮。

我初步估计内存占用的大头是 Dialer 这个拨号界面。因为它的 Layout 最复杂,有 LinearLayout,RelativeLayout 的嵌套。而且在 Layout 的编辑界面可以看到,Dialer 这个拨号界面竟然用了 36 张图片。
为了证实我的想法,我需要修改我们的 app 的代码。
为了保证 Voice 这个 Activity 中的三个 Fragment 切换顺畅,我们的代码中设置了 ViewPager 的
setOffscreenPageLimit(2);

参看 Android 官方开发页面:
https://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int) 。
从事 Android 开发的朋友对这个方法应该不陌生。
那么在我们三个 Fragment 的情况下,不管切换到哪一个 Fragment,都是一直保留三个 Fragment,不会销毁任何一个。
我把它改成:
setOffscreenPageLimit(1);
这样,当我进入到 Voice 这个 Activity 中的时候,因为默认是位于 History 这个 Fragment,那么只会加载 History 和 它右边的 Contacts 这两个 Fragment,而不会去加载 Dialer 这个 Fragment。
当我切换到 Contacts 这个位于中间的 Fragment 时,这三个 Fragment 都会被加载。我就可以看一下 只加载 History 和 Contacts 这两个 Fragment 与 加载三个 Fragment 时,内存使用有什么区别。
果不出所料,在内存监视器中,我发现:只加载 History 和 Contacts 这两个 Fragment,内存使用时 20 多 MB,而加载三个 Fragment 时就一下子攀升到 94.71 MB。

4. 解决内存使用过多
因此罪魁祸首就是 Dialer 这个 Fragment。
既然知道了内存使用过高的部分,那么我们就来优化一下。
进入 Dialer 这个 Fragment 的 Layout 文件(XML 文件),原本我以为是布局比较复杂的缘故。
我尽可能简化了布局,但是运行后占用内存几乎没什么改变。因为布局复杂影响性能并不是因为占用内存,而是嵌套所带来的绘制问题以及过度绘制,过度绘制占用的是 CPU 和 GPU。
我就想是不是每张图片占的资源多,图片数目又多的缘故。
我发现好些小部件的背景竟然用了两张不同的图片,分为「被按下」 和「没被按下」两种情况。
而拨号键盘上的 12 个按键的背景也是如此,每一个都用了两张图片来表示「被按下」 和「没被按下」两种情况。
而且 Dialer 这个 Fragment 中所用的图片的 resolution (分辨率)和图片本身大小都比较高。
因为我把背景都用 color (颜色值)来表示,去掉图片。把 Fragment 中所有的图片的分辨率和大小都重新设计,调到用户可接受的最小值。
经过优化,在进入 Voice 子界面后内存占用变成了如下图的 44.03 MB,比优化前的 94.71 MB 少了一半多。

经过测试,app 再也不会崩溃了。组长非常高兴,因为假如这个问题不解决,我们的新版代码就不能打包发给客户。

这篇文章因为没有公司产品的截图,因此纯文字的叙述比较难理解。还望大家见谅。

但解决这个问题,却让我受益匪浅。之前我一直用的比较多的是 Logcat 这个日志显示程序,没有怎么用过 Android Studio 自带的监视器。
现在我发现原来这个监视器这么有用,虽然在 Android 代码中我们也可以打印出内存使用量,但是没有监视器的实时变化来得直观。

5.总结
Android 开发中,在不影响用户体验的前提下,尽量降低图片的大小和分辨率,可以大幅度减少内存使用。

如何用androidstudio自带监控内存工具监控内存相关推荐

  1. AndroidStudio自带代码检测工具

    这是一款AndroidStudio自带的代码检测工具,个人认为其存在的价值在于代码优化,一方面预防错误率产生,一方面提升自我的优化意识 ~ 如果需要规范代码,也可以 使用 Android插件 - 阿里 ...

  2. AndroidStudio 自带UI检测工具Monitor

    Monitor  位置 Tools-->Android-->Android device Monitor Monitor 开启时               Window ---> ...

  3. Android踩内存工具,手机内存清理软件下载

    软件标签: 内存清理 主要功能 1.收集系统正在运行任务的详细信息 2.自定义内存清理模式,使系统运行畅快自如 3.进程切换,软件卸载一键完成 安卓手机清理内存到底有什么作用? 1.手机反应速度变快 ...

  4. 站点的监控小工具-监控宝

    在任何一个网站,或者个人的网站当中都希望自己提前预知自己网站的近期的状况,或者在出现问题前,能够得到最快的通知,以避免网站出现不良状况,保证其健康的运行:当然我们在生产中可能进程遇到Nagios.Ca ...

  5. JDK自带工具查看内存

    JDK自带工具查看内存 ​ 今天维护之前写的一个项目,在本地跑一会出现java.lang.OutOfMemoryError: PermGen space 所以这里说一下怎么解决这个问题,以及如何查看内 ...

  6. JAVA内存分析:使用JDK自带工具进行内存和CPU分析及垃圾回收

    JAVA内存分析:使用JDK自带工具进行内存和CPU分析及垃圾回收 JAVA内存分析一:基于dump内存溢出快照分析 JAVA内存分析二:idea集成jprofiler查看JVM内存使用情况 JAVA ...

  7. android profiler 简书,使用AndroidStudio提供的Android Profiler工具和mat进行内存泄漏分析...

    废话不多说直接说流程 给项目中集成LeakCanary工具进行内存泄漏检测.发现有内存泄漏后该工具会进行提示 有内存泄露后我们需要使用as的profiler工具进行分析并获取到.hprof文件,步骤如 ...

  8. windows7内存诊断工具有用吗_Win7怎么使用自带工具进行内存检测?

    电脑使用久了,总是会出现各种各样的问题,其中比较常见的就是内存问题了.出现内存问题,我们可以采用系统自带的工具进行内存检测,可是很多用户不知道Win7怎么使用自带工具进行内存检测,为此小编赶紧整理了以 ...

  9. 13.8.可视化虚拟机工具--Jconsole内存监控、13.9.可视化虚拟机工具--Jconsole线程监控、13.10.死锁原理以及可视化虚拟机工具--Jconsole线程

    13.8.可视化虚拟机工具–Jconsole内存监控 13.9.可视化虚拟机工具–Jconsole线程监控 13.10.死锁原理以及可视化虚拟机工具–Jconsole线程 13.8.可视化虚拟机工具– ...

最新文章

  1. 【从零学习openCV】IOS7下的人脸检測
  2. 如何破解root以及grub密码
  3. SQL查询所有客人的第一次用餐时间
  4. python3.8.3下载不了nltk_在ubuntu16.04+python3.5情况下安装nltk,以及gensim时pip3安装不成功的解决办法...
  5. php光标添加,JS在可编辑的div中的光标位置插入内容的方法_javascript技巧
  6. Go语言集合(Map)
  7. 3天超4亿 《阿丽塔:战斗天使》中国票房超北美
  8. 为什么有些工厂,3000块一个月不包吃住还能招到工人?
  9. 恭喜你,2018 中国开发者有奖大调查“榜上有名”!
  10. 10分钟入门Python,花5小时写了7个案例和这篇文章值得收藏
  11. 区块链技术应用与安全发展
  12. 基于飞桨实现高光谱影像和全色影像融合
  13. 山西内蒙古地区知名的调查研究咨询公司
  14. 项目管理学习——《构建之法》读书笔记
  15. Java第n次入门之画板的实现
  16. C1认证: 任务01-修改游戏存档和金币
  17. Chinese Segmentation Introduction
  18. 【ADS867x】14 位 500kSPS 4/8 通道 ADC 简介及驱动应用示例
  19. 基于AutoHotkey的智能翻译器
  20. ant design pro v4 从后台服务器请求菜单,思路,具体代码及坑

热门文章

  1. [资源]Python资源大全中文版
  2. 物理机如何安装Linux centos7
  3. oracle 中的pi,Oracle中实现圆周率计算(一)
  4. Ubuntu1804下的Melodic版本Moveit和OMPL的源码安装,并自定义规划算法在Moveit上使用
  5. 第三章 区块链技术架构与发展趋势
  6. win10 ,在任务栏上,设置快速启动栏
  7. 探秘区块链之全局介绍
  8. Win10怎么优化网络?网络优化设置
  9. Linux下开启openmp编译,OpenMP程序的编译和运行
  10. chromium 编译