继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

android性能优化全方面解析(一)

慕哥9229398
关注TA
已关注
手记 1099
粉丝 198
获赞 911

公司的新需求终于解决完了,离测试和发布还有段时间,第一次体验了下没需求没bug的感觉,真是舒爽~然后翻了翻有什么可以学的。无意翻到了Android后期发展的五大趋势。一、性能优化。二、高级UI。三、JNI/NDK开发。四、架构师。五、RN开发。这也许将会是我的进阶趋势。早已知道在瓶颈期的我,似乎看到了突破的希望的。

其实,关注我的或者在群里的小伙伴也知道,UI那块我问题不大。但是高级UI就有难度了。我们先不管他,一个一个来。先从性能优化来。其实我是拒绝写这篇文章的。为什么?性能优化的分类很多,一个分类写一篇感觉篇幅量很小,结合在一起写有感觉很大。而我目前打算整体的整理一下。

那么我们先分析下性能优化有那几个方面:一、内存优化。二、UI优化(布局优化和绘制优化)。三、速度的优化(线程优化/网络优化)。四、电量优化。五、启动优化。应该就这些了。那么这只是五大方面,里面还结合了各种细节方面的。不急,我们下面一个个的介绍。

内存优化

关于性能优化我们可以不知道其他的,但一定要知道内存优化。因为内存泄漏可以Android的常客。那么什么是内存泄漏呢?内存不在GC的掌控范围之内了。那么java的GC内存回收机制是什么?某对象不在有任何引用的时候才会进行回收。那么GC回收机制的原理是什么?又或者说可以作为GC Root引用点的是啥?或许有人听不懂我在讲啥。我们先来看张图。

![(F~1JUF)]OXP@1GI@M3C9F8.png](https://upload-images.jianshu.io/upload_images/15405197-99262815d60e130b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

当我们向上寻找,一直寻找到GC Root的时候,此对象不会进行回收,例如,一个Activity。那么如果我们向上寻找,直到找到GC Root对象的时候,就说明它是不可以回收的,例如,我定义了一个int a;但是这个数据,我整个页面或者说整个项目都没有用到,则这个对象会被GC掉。

GC的引用点

<pre class="prettyprint" style="box-sizing: inherit; font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 16px; overflow: auto; max-width: 100%; margin: 0px 0px 30px; padding: 20px 25px; white-space: pre-wrap; word-wrap: break-word; border: 0px; border-radius: 3px; background-color: rgb(244, 246, 249); line-height: 1.875; color: rgb(112, 112, 123); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">1. java栈中引用的对象
2. 方法静态引用的对象
3. 方法常量引用的对象
4. Native中JNI引用的对象
5. Thread——“活着的”线程</pre>

如何判断

那么我们如何判断一个对象是一个垃圾对象,可以讲他进行回收呢?举了小例子教你们如何区分:

<pre class="prettyprint" style="box-sizing: inherit; font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: 16px; overflow: auto; max-width: 100%; margin: 0px 0px 30px; padding: 20px 25px; white-space: pre-wrap; word-wrap: break-word; border: 0px; border-radius: 3px; background-color: rgb(244, 246, 249); line-height: 1.875; color: rgb(112, 112, 123); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">一般在学校吃饭,我们有两种情况,第一:吃完饭就直接走人,碗筷留给阿姨来收拾处理。
第二:吃完之后把碗筷放到收盘处直接进行回收。
但我们是个有素质的人,一般采用第二种情况,但根据想法,我们更倾向于第一种。
那么一般在饭店或者KFC中,都是第一种情况。
那么此时,问题来了,如果我已经吃完饭,然后我并没有离开饭店,做在位置上和朋友吹吹牛逼,谈谈理想,聊聊人生。
那么桌上那一堆碗筷是收还是不收?讲道理是不能收的。虽然实际也是不能收的。因为顾客是上帝~~~
</pre>

So,我们如何判断一个对象是一个可回收的垃圾对象呢?这是我们的一个主观的判断。但是有种情况我们是必须要考虑到的,没错,就是内存过多无法释放的时候,会直接导致OOM。整个项目boom炸了。什么鬼?outofmemory。没错就是它。

内存溢出

分析原因

我们需要分析内存溢出的原因,我们先来看一张图:

![LRHJ{H9B65B2I]WGR4V7L~P.png](https://upload-images.jianshu.io/upload_images/15405197-4a90edd7accb8922.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

内存泄漏一般导致应用卡顿,极端情况会导致项目boom。Boom的原因是因为超过内存的阈值。

原因主要有两方面:
  • 代码存在泄漏,内存无法及时释放导致oom(这个我们后面说)

  • 一些逻辑消耗了大量内存,无法及时释放或者超过导致oom

所谓消耗大量的内存的,绝大多数是因为图片加载。这是我们oom出现最频繁的地方。我前面有写过图片加载的方法,一个是控制每次加载的数量,第二,保证每次滑动的时候不进行加载,滑动完进行加载。一般情况使用先进后出,而不是先进先出。不过一般我们图片加载都是使用fresco或者Glide等开源库。

我们来看下下面两张图:

webp

image


webp

image

对比两张图,我们可以在第一张的情况出现了oom情况,我们通过log打印发现,处理的好像没什么问题,换句话说,如果我不放那0.8M的图片。然后继续不停的操作同样会出现OOM,然而我们就蒙了。没什么图片加载怎么就这么崩掉了。


如何查看

首先,我们确定我们项目或者某几个类里面是否存在内存溢出的问题。我们可以通过如下方法:

  • Android–>System Information–>MemoryUsage查看Object里面是否有没有被释放的Views和Activity

  • 命令行模式:adb shell dumpsys meminfo 包名 -d

就那我公司的项目举例把。首先,我们在这边可以看到memory。CPU和net的使用情况。

webp

image


我们找到Object。看看我们内存的消耗情况。

webp

image


随便这么一看,尼玛蛋,1300左右的view和一个Activity。还有3个context。可怕。。可以理解为一个Activity里面使用了将近1300个view。。。想都不敢想。。。

我们可以通过看Memory Monitor工具。 检查一个一个的动作。(比如Activity的跳转)。反复多次执行某一个操作,不断的通过这个工具查看内存的大概变化情况。 前后两个内存变化增加了不少。

我们可以更仔细的查找泄漏的位置,在AS里面使用 Heap SnapShot工具(堆栈快照)。如图所示:

webp

image


我们点击后,他会进行一段时间的监控,然后会生成一个文件。我们点击我们package tree view。

webp

image


我们找到自己项目的包名。然后进行进一步的分析。首先看一下2个列表的列名到底指的什么。

webp

image


实例化对象的详细信息:

webp

image


我们来随便的看一下内存中的数量:

webp

image



作者:Android征途
链接:https://www.jianshu.com/p/3dc39d3919f1


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP