EN

Android Performance

闻道有先后,术业有专攻,如是而已

loading
Android 内存优化之三 - 打开 MAT 中的 Bitmap 原图

本文是 MAT 工具使用系列的第二篇,这个系列共三篇,详细介绍了如何使用 MAT 来分析内存问题,既可以是 Java 应用的内存问题,也可以是 Android 应用的内存问题:

  1. Android 内存优化之一:MAT 使用入门
  2. Android内存优化之二:MAT使用进阶
  3. Android内存优化之三:打开MAT中的Bitmap原图

本文介绍的是从 MAT 里手工还原 Bitmap 原图的旧排查技巧,适合在离线 heap 里确认“到底是哪张图”被错误持有。现在排查图片内存问题时,第一步通常不是直接打开 MAT,而是先用 Android Studio Memory Profiler 的 heap dump/retained size/reference 视图确认 Bitmap、BitmapDrawable 或图片缓存的持有链;如果问题涉及 Native Bitmap、纹理、图片库缓存或系统内存压力,还需要结合 dumpsys meminfo、Perfetto/native heap profiling、图片库自身缓存统计一起判断。MAT 仍然可以作为最后的离线取证工具,而不是默认入口。

在使用MAT查看应用程序内存使用情况的时候,我们经常会碰到Bitmap对象以及BitmapDrawable$BitmapState对象,而且在内存使用上,Bitmap所占用的内存占大多数.在这样的情况下, Bitmap所造成的内存泄露尤其严重, 需要及时发现并且及时处理.在这样的需求下, 当我们在MAT中发现和图片相关的内存泄露的时候, 如果能知道是那一张图片,对分析问题会有很大的帮助.

本文就介绍如何将MAT中的Bitmap数组对象还原成一张图片。

Android 内存优化之二 - MAT使用进阶

本文是 MAT 工具使用系列的第二篇,这个系列共三篇,详细介绍了如何使用 MAT 来分析内存问题,既可以是 Java 应用的内存问题,也可以是 Android 应用的内存问题:

  1. Android 内存优化之一:MAT 使用入门
  2. Android内存优化之二:MAT使用进阶
  3. Android内存优化之三:打开MAT中的Bitmap原图

本文的 Histogram、Dominator Tree、Thread 信息仍然是 heap 分析的核心方法,但抓取和第一轮分析入口应换成现在的工具链:先用 Android Studio Memory Profiler 捕获 heap dump,必要时在关键点调用 Debug.dumpHprofData(),再用 Profiler 的 retained size、reference 和 Activity/Fragment leak 过滤做初筛;如果要离线做大文件分析,再导出 .hprof 并按需用 hprof-conv 转给 MAT。对于线上或自动化场景,LeakCanary 更适合做泄漏发现,dumpsys meminfo/Perfetto/native allocation recording 更适合补齐 Java heap 之外的内存证据。

Java的内存泄露的特点

  • Java中的内存泄露主要特征:可达,无用
  • 无用指的是创建了但是不再使用之后没有释放
  • 能重用但是却创建了新的对象进行处理

MAT使用技巧进阶

使用Android Studio Dump内存文件

Android Studio的最新版本可以直接获取hprof文件:

Android-Studio

Android 内存优化(1) - MAT 使用入门

本文是 MAT 工具使用系列的第一篇,这个系列共三篇,详细介绍了如何使用 MAT 来分析内存问题,既可以是 Java 应用的内存问题,也可以是 Android 应用的内存问题:

  1. Android 内存优化(1) - MAT 使用入门
  2. Android 内存优化(2) - MAT使用进阶
  3. Android 内存优化(3) - 打开MAT中的Bitmap原图

这组文章里的 MAT 技巧仍然适合学习 Java heap、Dominator Tree、Retained Size、引用链这些基础概念,但默认抓取流程已经变了。早期流程是 Eclipse/DDMS 导出 Android HPROF,再用 hprof-conv 转成 MAT 能读的格式;现在应优先在 Android Studio Memory Profiler 里直接 Capture heap dump,先用 Android Studio 的 class/package、retained size、reference 视图定位,再在需要离线处理大 HPROF 或做更复杂 Dominator Tree 分析时导出给 MAT。泄漏检测优先接入 LeakCanary,系统/Native 内存问题则要结合 dumpsys meminfo、Android Studio native allocation recording 或 Perfetto native heap profiling,而不是只看 MAT。

MAT简介

MAT介绍

MAT(Memory Analyzer Tool),一个基于 Eclipse 的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。

image

当然MAT也有独立的不依赖Eclipse的版本,只不过这个版本在调试Android内存的时候,需要将DDMS生成的文件进行转换,才可以在独立版本的MAT上打开。不过Android SDK中已经提供了这个Tools,所以使用起来也是很方便的。

Android性能优化后续

前言

本文是一篇译文,原文Android Performance Case Study Follow-up的作者是大名鼎鼎的Romain Guy。本文讲述了Android性能优化的一些技巧、方法和工具。

译文正文

两年前,我发表了一篇名为Android Performance Case Study 的文章,来帮助Android开发者了解需要使用什么工具和技术手段来确定、追踪和优化性能问题。

那篇文章以一个Twitter客户端 Falcon Pro为典范,其开发人员为 Joaquim Vergès. Joaquim人不错,他允许我在我的文章中使用它的程序作为例子,并且快速处理了我发现的所有问题。一切都OK,直到Joaquim 从头开始开发Falcon Pro 3,前不久在他准备发布它的新应用的时候,他联系了我,因为他有一个和滚动相关的性能问题需要我来帮助他,这一次我依然没有源代码可以参考。

Android 小技巧 - 5

本文是一篇译文,这篇是这个系列的第五篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方坐在并没有将这个工具的作用讲出来,我会补充上去.

第五篇里 SDK “以为没有其实有”的功能比较多:ViewDragHelper 帮你做自定义拖拽容器、PopupWindow 实现非 Activity 的临时浮层、ThumbnailUtils 直接生成图片或视频缩略图、ActivityOptions 自定义 Activity 跳转动画与 launch display;性能向的有 SparseArray 替代 HashMap<Integer, *>、SQLiteDatabase.yieldIfContendedSafely 在大事务里给其他线程让路;偏维护性的有 PackageManager.setComponentEnabledSetting 动态开关组件、Context.createConfigurationContext 拿到指定配置下的资源、View.generateViewId 避免 id 冲突。

Android 小技巧 - 4

本文是一篇译文,这篇是这个系列的第四篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方坐在并没有将这个工具的作用讲出来,我会补充上去.

第四篇集中讲两类东西:一类是被 XML 属性藏起来的特性,android:weightSum、android:duplicateParentState、android:clipChildren、android:fillViewport、android:tileMode、android:scaleType 这些点一上手就能直接省一段自定义 View 的代码;另一类是 SDK 里靠搜文档才能发现的工具,Activity.isChangingConfigurations 区分配置变化导致的销毁、ViewTreeObserver 监听布局节点变化、DatabaseUtils 处理 Cursor 与 ContentValues、AtomicFile 保证文件读写原子性、Layout 里的 <merge> 节省层级。

Android 小技巧 -3

本文是一篇译文,这篇是这个系列的第三篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方坐在并没有将这个工具的作用讲出来,我会补充上去.

第三篇的关键词是”原本写过却懒得查文档的事情”:UrlQuerySanitizer 替你解析 query 参数、PhoneNumberUtils.formatNumber 帮你按区域格式化电话号码、LocalBroadcastManager 让进程内广播省去权限和跨进程开销;Fragment 相关有 setArguments 与 DialogFragment.setShowsDialog 这种容易忽略的设计点;调试侧有 Application.registerActivityLifecycleCallbacks 监听全局生命周期、BroadcastReceiver.setDebugUnregister 排查泄漏、Activity.recreate 切换配置时快速验证。

为 Nexus5 编译 AndroidL 固件

接前一篇文章使用Android Studio查看Android Lollipop源码, 我们知道,仅仅看代码,提高是比较有限的,而且理解起来也比较肤浅,往往过目就忘. 而自己写过的代码,往往会印象比较深刻,在写的时候也会比较容易理解流程. 所以我们在看代码的同时, 如果能修改代码, 在手机上跑起来并看到修改的效果,这无疑会加快看代码的效率和积极性. 所以这篇文章,就讲解一下如何自己编译AndroidL的源码,并且在Nexus5上跑起来. 至于为何需要自己编译固件,而不是直接安装Google给出的工厂固件?原因是Google给出的工厂固件是User版本,是没法随心所欲Push东西进去的. 所以我们需要编译自己的Userdebug版本.

本文假设你已经下载了AndroidL的源码,并且有一台Nexus5手机(手机系统开发人员必备), 如果你还没有AndroidL的源码,或者你有源码但是没有配置编译的环境,那么 Initializing a Build Environment 和Downloading the Source这两篇文章你应该先去看一下。如果访问官方文档或下载源码不顺畅,需要先处理网络与源码获取环境。这后面的教程Google官网也有教程.所以我只针对Nexus5进行讲解.

另外你需要知道AOSP,AOSP即Android Open Source Project 汉语意思是:谷歌开放源代码项目.我们通过Google官方下载的源代码,就是AOSP的代码, 其中是不包含Google开发的那些个应用的,各个厂商拿到的也是这个版本,在这个版本的基础上进行修改. 而Google发布的工厂固件则是包含全套Google服务的. 厂商如果想安装Google服务,就需要过Google的那一套认证,比较麻烦,而且价格不菲,鉴于Google在国内的尴尬地位,国内很多厂商都没有过这个认证.

Android 性能优化之 Systrace 工具介绍(一)

这篇是 2015 年的 Systrace 工具介绍,里面提到的 Eclipse、Device Monitor、sdk/tools/systrace、User 版本不能抓 Trace 等流程,已经不适合作为今天的默认操作路径。旧文章保留的是 Systrace 的基本概念:它为什么能把 SurfaceFlinger、WindowManager、View、CPU 调度等系统行为放到一张时间线上。今天真正抓取和分析 Trace,应优先看 Android Perfetto 系列目录。

现在的工具流程可以直接按下面理解:

旧流程 新流程
Eclipse / Android Studio Device Monitor 里点 Systrace 开发者选项里打开 System Tracing,或使用 adb shell perfetto
python systrace.py --time=10 -o trace.html ... adb shell perfetto -t 10s -b 64mb ... --out /data/misc/perfetto-traces/trace.perfetto-trace
输出 HTML,用 Chrome 打开 输出 .perfetto-trace,用 Perfetto UI 或 trace_processor 打开
主要靠肉眼在 HTML 里缩放和点击 先看轨道和 Slice,再结合搜索、SQL、metrics 做证据收敛
User 版本基本不可用 User 版本可以先抓有限信息;系统级细节仍建议 Userdebug/eng

本文是Android性能优化工具系列的第一篇,这个系列主要介绍Android性能优化过程中会使用到的一些工具,以及如何用这些工具来发现问题和解决问题。在性能优化方面,Android有不少性能工具供大家来使用,按照我们一贯地 “发现问题-解决问题”的思路来看,发现问题才是最主要的,一上来就想着如何去解决问题,反而会事倍功半。

这一篇先来简单介绍一下Systrace这个工具。

Systrace简单介绍

Systrace是Android4.1中新增的性能数据采样和分析工具。它可帮助开发者收集Android关键子系统(如surfaceflinger、WindowManagerService等Framework部分关键模块、服务,View系统等)的运行信息,从而帮助开发者更直观的分析系统瓶颈,改进性能。

Systrace的功能包括跟踪系统的I/O操作、内核工作队列、CPU负载以及Android各个子系统的运行状况等。在Android平台中,它主要由3部分组成:

  • 内核部分:Systrace利用了Linux Kernel中的ftrace功能。所以,如果要使用Systrace的话,必须开启kernel中和ftrace相关的模块。
  • 数据采集部分:Android定义了一个Trace类。应用程序可利用该类把统计信息输出给ftrace。同时,Android还有一个atrace程序,它可以从ftrace中读取统计信息然后交给数据分析工具来处理。
  • 数据分析工具:Android提供一个systrace.py(python脚本文件,位于Android SDK目录/tools/systrace中,其内部将调用atrace程序)用来配置数据采集的方式(如采集数据的标签、输出文件名等)和收集ftrace统计数据并生成一个结果网页文件供用户查看。 从实现关系看,Systrace是对Linux Kernel中ftrace的封装。应用进程需要利用Android提供的Trace类来使用Systrace.
    关于Systrace的官方介绍和使用可以看这里:Systrace
使用 Android Studio 查看 Android Lollipop 源码

Android Studio

作为Google的亲儿子,Nexus手机系列所收到的待遇大家有目共睹.Android5.0出来之后,Nexus5第一时间就升级到了最新的系统.那么作为Google亲儿子的Android Studio同样备受Google的重视,我也是第一时间从Eclipse转投到了Android Studio的怀抱中,从最初的测试版本一路升级到现在的1.0正式版本(今天发布了1.1,果断已经升级了).

Android 性能优化之过渡绘制 - 实战篇

前言

上一篇文章从理论的角度讲解了一下什么是过渡绘制,以及可以用来查看和确认过渡绘制的工具,还提供了一些优化过渡绘制的方法。对代码和布局比较熟悉的人,看完上一篇其实就已经可以对自己的应用进行优化了。我记得有人说过,用iphone你只需要保证苹果有节操即可,用Android你就得保证所有的Android开发者都有节操。但现实是残酷的,现在Android市场上,有很多粗制滥造的应用,其中不乏大厂之作,各位打开过渡绘制按钮,就知道我所言非虚。作为一个Android开发人员,我肯定是更希望Android能一步一步好起来,超越iphone。

这篇文章从实战的角度,讲解了一个过渡绘制的优化过程。当然这里用到的只是很少的一部分,毕竟每个应用差别很大,优化方式也各不一样。所以这篇文章仅供参考,想把这块做好还是要下功夫的。

如果没有看过前一篇,可以点这里:Android性能优化之过渡绘制(一)


Android 性能优化之过渡绘制 - 理论篇

博客有一段时间没有更新了,到了新公司后,一直比较忙,博客也更新地不那么频繁了。最近一直在看Android上和性能相关的部分,也就是所谓的Android性能优化,才发现Android性能这一块,自己懂得还是太少了,所以从上层开始看,也算是一点一点入门吧。这个系列将讲解学习过程中总结的和性能相关的内容。

首先将讲解一下GPU过渡绘制,也是开发者最直接接触的部分吧,这个内容将分为两个部分来将讲,第一部分初步讲解一下gpu过渡绘制的原理,和一些优化建议,第二部分将用实际例子来讲解优化GPU过渡绘制的一般步骤。

过渡绘制概念

GPU过渡绘制的概念:GPU过度绘制指的是在屏幕一个像素上绘制多次(超过一次),比如一个TextView后有背景,那么显示文本的像素至少绘了两次,一次是背景,一次是文本。GPU过度绘制或多或少对性能有些影响,设备的内存带宽是有限的,当过度绘制导致应用需要更多的带宽(超过了可用带宽)的时候性能就会降低。带宽的限制每个设备都可能是不一样的。

Android 小技巧 - 如何让EditText不自动获取焦点
Android中,使用EditText作为输入框很方便,但是有时候EditText会自动获取焦点,其行为:点击进入这个页面后,EditText自动获取焦点,导致软键盘直接跳出.有时候这么做很方便,但是大部分时候我们还是希望在点击EditText的时候,软键盘才弹出来. 这里有个很简单也很实用的技巧,即在EditText的父Layout中,加入下面的两个属性即可: android:focusable="true" android:focusableInTouchMode="true" 这样做的原理是让用户进入到这个页面之后,EditText的父控件 获取焦点,这样的话EditText就获取...
Android 小技巧 -2

本文是一篇译文,这篇是这个系列的第二篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方坐在并没有将这个工具的作用讲出来,我会补充上去.

第二篇里挑出来的 API 大多是工具级别的:DateUtils.formatDateTime 直接帮你按系统区域格式化日期、Formatter.formatFileSize 处理文件大小的本地化显示、AlarmManager.setInexactRepeating 用粗略间隔合并闹钟事件来省电;UI 侧有 StaticLayout 自己控制文字测量、ViewStub 延迟 inflate、GestureDetector 拼装常见手势;还有 Linkify 自动识别文本里的链接、ActivityManager.getMemoryClass 判断当前进程内存上限、Pair.create 这种小到容易忘的工具。

Android 小技巧 - 1

本文是一篇译文,这篇是这个系列的第一篇.讲述的是Android开发中遇到的一些好用的小技巧,或者一些实用的API,很多人都知道,但也有人不知道,记录下来,如果能帮助到大家,也是极好的.由于不是严格的博文,所以翻译也不那么严格,有些工具和类我也会经常用,所以我会根据自己的想法去写.有些地方坐在并没有将这个工具的作用讲出来,我会补充上去.

第一篇里挑出来的都是 SDK 里早就存在但容易被忽略的小工具:批量启动 Activity 的 startActivities、统一手势识别阈值的 ViewConfiguration、写 Adapter 几乎一定用得到的 LayoutInflater.from,还有 Space、ContextThemeWrapper、ArgbEvaluator 这种很少被介绍但用上一次就忘不掉的类。下面正文按 API 逐条列出,每条都带官方文档链接和简短的使用建议。