作者:李泽玲
在软件测试中,如果想在一个耗时严重的操作中找出其耗时的瓶颈时,一般采用的方法是在每个被调用的函数中写进测试代码,在运行时打出日志。如果该操作涉及到的业务逻辑特别复杂时,插入这些测试代码不仅工作量十分巨大,而且难以维护。如果后期剔除不干净,不仅增加了无关的代码量,还会在执行时造成不必要的资源浪费。
像在手机管家的清理加速模块中,垃圾扫描这个功能的耗时是性能优化的重点,如何快速测试和分析扫描过程中的函数耗时一直是性能测试想克服的难题。但是在数以千计的函数中插入测试代码简直是一场恶梦,所以优化过程一直是不知道从何开始从何结束。这时候好想有个脚本可以跟踪调用关系,并且可以根据规则自动插入测试代码。
像在手机管家的清理加速模块中,垃圾扫描这个功能的耗时是性能优化的重点,如何快速测试和分析扫描过程中的函数耗时一直是性能测试想克服的难题。但是在数以千计的函数中插入测试代码简直是一场恶梦,所以优化过程一直是不知道从何开始从何结束。这时候好想有个脚本可以跟踪调用关系,并且可以根据规则自动插入测试代码。
它是一种可以通过预编译方式和运行期间的动态代理实现的编程技术,在不修改源代码的情况下给程序统一添加某种功能,共享一个行为,主要可用来作为日志记录,性能统计,安全控制和事务处理等等。而且最重要的是,打包时可以通过不同的编译选项选择插入或者剔除测试代码,真正做到无损插桩!啊!果然很适合这种性能调优场景,赶紧学起来!
面向切面编程思想中有两个核心的步骤:
1.在软件中挑选出来需要关注的切面关注点(pointcut),即程序中我们选择出来的执行点的集合,选择出来之后就可以对其进行后续操作,比如性能调优这里选择了手机管家中的 sdcard 卡扫描这个关注点,这里可以通过通配符组合各种规则来选取一系列的函数;
2.在切面上增加一些需要统一执行的操作(advice),比如统一给切面选取到的函数添加统计耗时的代码, 这里主要有三种类型,分别是:
具体示意图如下,看不懂也没关系,下面还会有具体代码的演示。
AOP 这么厉害,所以到底怎么应用到具体工程上。对于 java、C++ 都已经有了对应的 AOP 支持版本,aspectj 就是基于 java 易用的、功能强大的 aop 编程语言。在 eclipse 中安装 AJDT 插件就可以快速对工程进行插桩。
在刚刚简介的基础上了解 AOP 的基本思想,接下来通过 aspectJ 实战脚本的例子深入了解下如何对你的程序进行自动插桩吧。
我的程序功能很复杂,在测试 CPU 使用率时总发现一个现象,灭屏时进程的 CPU 使用率会突然升高,现有的 log 无法发现问题,想看看这是灭屏后程序到底有没有做什么异常操作,有没有异常调用其他不相关函数,这时候该怎么办?
用法详解:
用法:打完插桩包后,安装后,打开被插桩过的软件,logcat 中自动输出每个清理相关函数的函数名,此时便可查看是否有异常调用。
业务中有个扫描的函数,想查看在扫描执行过程中该函数调用到的每个函数运行耗时,查看耗时瓶颈,以定位最应优化的函数
pointcut 定义详解:
advice 定义详解:
用法:安装插桩包后,通过 logcat 收集日志中各个函数耗时,得到扫描过程中每个函数过程中的耗时和被调用次数,查看扫描瓶颈。如果输出函数过多,还可以使用 HashMap 对每个函数的调用次数和总耗时进行统计,最后输出最终结果。
测试过程中想监控一个函数,如果其耗时(或者其他指标)超过预定的最大值,则为异常情况,想输出异常情况下函数的调用行数和调用堆栈
用法详解:
用法:安装插桩包,触发业务逻辑,查看日志输出,定位异常路径
由于篇幅的局限,这里只是通过一些例子简单地讲解了 AOP 的相关应用。作为一种新的程序设计模式,AOP 还蕴含着更多的能力,不仅仅适用于性能调优上,还能应用在开发上,它能将逻辑代码和处理琐碎事务的代码分离开,减少代码实现和维护的复杂度。
更多的 AOP 和 aspectJ 的学习资料可以参考下面链接:
(1)https://eclipse.org/aspectj/doc/released/adk15notebook/index.html 官方 aspectJ 开发者文档
(2)http://blog.csdn.net/zl3450341/article/details/7673938 详细的 aspectJ 语法中文讲解
本章完~
原文链接:enter link description here
扫码关注我们