正文
命令行模式:adb shell dumpsys meminfo 包名 -d
就那我公司的项目举例把。首先,我们在这边可以看到memory。CPU和net的使用情况。
我们找到Object。看看我们内存的消耗情况。
随便这么一看,1300左右的view和一个Activity,还有3个context——可以理解为一个Activity里面使用了将近1300个view,想都不敢想。
我们可以通过看Memory Monitor工具,检查一个一个的动作(比如Activity的跳转)。反复多次执行某一个操作,不断通过这个工具查看内存的大概变化情况。 前后两个内存变化增加了不少。
我们可以更仔细查找泄漏的位置,在AS里面使用 Heap SnapShot工具(堆栈快照)。如图所示:
我们点击后,他会进行一段时间的监控,然后会生成一个文件。我们点击我们package tree view。
我们找到自己项目的包名。然后进行进一步的分析。首先看一下2个列表的列名到底指的什么。
实例化对象的详细信息:
我们来简单看一下内存中的数量:
这还是我们刚进手机,一个bean就被调用了这么多次。简直可怕。这个我们可以通过内存分析工具解决的。
内存分析工具
性能优化工具:
第三方分析工具:
-
MemoryAnalyzer
-
GT Home
-
iTest
因为我没有这些工具,无法进行演示。
注意事项
-
我们尽量不要使用Activity的上下文,而是使用application的上下文,因为application的生命周期长,进程退出时才会被销毁。所以,单例模式是最容易造成内存溢出的原本所在,因为单例模式的生命周期的应该和application的生命周期一样长,而不是和Activity的相同。
-
Animation也会导致内存溢出,为什么?因为我们是通过view来进行演示的,导致view被Activity持有,而Activity又持有view。最后因为Activity无法释放,导致内存泄漏。解决方法是在Activity的ondestory()方法中调用Animation.cancle()进行停止,当然一些简单的动画我们可以通过自定义view来解决。至少我现在已经很少使用Animation了。没有一个动画是自定义view解决不了的。如果有,那就是两个。
UI优化主要包括布局优化以及view的绘制优化。不急,我们接下来一个一个慢慢看~~。先说下UI的优化到底是什么?有些时候我们打开某个软件,会出现卡顿的情况。这就是UI的问题。那么我们想一下,什么情况会导致卡顿呢?一般是如下几种情况:
1. 人为在UI线程中做轻微耗时操作,导致UI线程卡顿;
2. 布局Layout过于复杂,无法在16ms内完成渲染;
3. 同一时间动画执行的次数过多,导致CPU或GPU负载过重;
4. View过度绘制,导致某些像素在同一帧时间内被绘制多次,从而使CPU或GPU负载过重;
5. View频繁的触发measure、layout,导致measure、layout累计耗时过多及整个View频繁的重新渲染;
6. 内存频繁触发GC过多(同一帧中频繁创建内存),导致暂时阻塞渲染操作;
7. 冗余资源及逻辑等导致加载和执行缓慢;
8. 臭名昭著的ANR。
可以看见,上面这些导致卡顿的原因都是我们平时开发中非常常见的。有些人可能会觉得自己的应用用着还蛮OK的,其实那是因为你没进行一些瞬时测试和压力测试,一旦在这种环境下运行你的App你就会发现很多性能问题。
布局优化
GPU绘制
我们对于UI性能的优化还可以通过开发者选项中的GPU过度绘制工具来进行分析。在设置->开发者选项->调试GPU过度绘制(不同设备可能位置或者叫法不同)中打开调试后可以看见如下图(对settings当前界面过度绘制进行分析):