性能优化全方面解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39735504/article/details/79421473

内存溢出

分析原因

我们需要分析内存溢出的原因,我们先来看一张图: 
这里写图片描述 
内存泄漏一般导致应用卡顿,极端情况会导致项目boom。Boom的原因是因为超过内存的阈值。 
原因主要有两方面:

  • 代码存在泄漏,内存无法及时释放导致oom(这个我们后面说)
  • 一些逻辑消耗了大量内存,无法及时释放或者超过导致oom

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

这里写图片描述 

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

如何查看

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

  • Android–>System Information–>MemoryUsage查看Object里面是否有没有被释放的Views和Activity
  • 命令行模式: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就被调用了这么多次。简直可怕。这个我们可以通过内存分析工具解决的。

UI优化

UI优化主要包括布局优化以及view的绘制优化。一般是如下几种情况:

  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;

布局优化

GPU绘制

我们对于UI性能的优化还可以通过开发者选项中的GPU过度绘制工具来进行分析。在设置->开发者选项->调试GPU过度绘制(不同设备可能位置或者叫法不同)中打开调试后可以看见如下图(对settings当前界面过度绘制进行分析): 
这里写图片描述

这里写图片描述 
这图看着太乱,我们来一张简洁明了的图: 
这里写图片描述 
我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。

可以发现,开启后在我们想要调试的应用界面中可以看到各种颜色的区域,具体含义如下: 
这里写图片描述

Overdraw有时候是因为你的UI布局存在大量重叠的部分,还有的时候是因为非必须的重叠背景。例如某个Activity有一个背景,然后里面的Layout又有自己的背景,同时子View又分别有自己的背景。仅仅是通过移除非必须的背景图片,这就能够减少大量的红色Overdraw区域,增加蓝色区域的占比。这一措施能够显著提升程序性能。

如果布局中既能采用RealtiveLayout和LinearLayout,那么直接使用LinearLayout,因为Relativelayout的布局比较复杂,绘制的时候需要花费更多的CPU时间。如果需要多个LinearLayout或者Framelayout嵌套,那么可采用Relativelayout。因为多层嵌套导致布局的绘制有大部分是重复的,这会减少程序的性能。

GPU呈现模式分析

我们依旧打开设置–>开发者选项–>GPU呈现模式分析–>在屏幕上显示为条形图,如图所示: 
这里写图片描述 
这里写图片描述 
当然,也可以在执行完UI滑动操作后在命令行输入如下命令查看命令行打印的GPU渲染数据(分析依据:Draw + Process + Execute = 完整的显示一帧时间 < 16ms):

adb shell dumpsys gfxinfo [应用包名]
  • 1

随着界面的刷新,界面上会以实时柱状图来显示每帧的渲染时间,柱状图越高表示渲染时间越长,每个柱状图偏上都有一根代表16ms基准的绿色横线,每一条竖着的柱状线都包含三部分(蓝色代表测量绘制Display List的时间,红色代表OpenGL渲染Display List所需要的时间,黄色代表CPU等待GPU处理的时间),只要我们每一帧的总时间低于基准线就不会发生UI卡顿问题(个别超出基准线其实也不算啥问题的)。

代码优化

Android Studio和IntellJ idead都有自带的代码检查工具。打开Analyze->Run Inspection by Name… –>unused resource 点击开始检测,等待一下后会发现如下结果: 
这里写图片描述

我们还可以这样,将鼠标放在代码区点击右键->Analyze->Inspect Code–>界面选择你要检测的模块->点击确认开始检测,等待一下后会发现如下结果: 
这里写图片描述 
当然,我这只是截取了少一部分,我们看下下面那个提示:@param v tag description is missing 。意味着v的类型缺少了,要么补上介绍,要么直接删除。

上面那两种方法是最容易找到代码缺陷以及无用代码的地方。

网络优化

线程是我们项目中不可缺少的重要部分,因为我们大多数数据都是从网络获取的。So,线程这个是必备用品。 
我们依旧可以通过Memory下面的Net进行网络的监听: 
这里写图片描述

ANR问题

application not responding。应用程序无响应。那么一般什么时候会出现ANR。Android官方规定:activity如果5s内无响应事件(屏幕触摸事件或者键盘输入事件)。BroadcastReceiver如果在10s内无法处理完成。Service如果20s内无法处理完成。这三种情况会导致ANR。用张简洁的图来介绍把。
这里写图片描述

线程优化

上面说的三种导致ANR的情况,绝大多数就是因为线程阻塞导致的。那么我们应该如何处理呢?Android系统为我们提供了若干组工具类来解决此问题。

  • Asynctask:为UI线程与工作线程之间进行快速处理的切换提供一种简单便捷的机制。适用于当下立即需要启动,但是异步执行的生命周期短暂的场景。

  • HandlerThread:为某些回调方法或者等待某些执行任务的执行设置一个专属的线程,并提供线程任务的调度机制。

  • ThreadPool:把任务分解成不同的单元,分发到各个不同的线程上,进行同时并发处理。

  • IntentService:适合执行由Ui触发的后台任务。并可以把这些任务执行的情况通过一定的机制反馈给UI。


阅读更多
换一批

没有更多推荐了,返回首页