分析应用程序能够帮助我们确定以下问题:
调用频率 有时,我们会多次调用一些计算代价昂贵(耗时)的方法,而这些调用是不必要的。通过识别那些经常被调用的方法,我们能够在调节性能的过程中,专注于应用程序中对性能影响最大的地方。
方法耗时 性能分析工具能够告诉我们一个调用特定方法所消耗的时间。如果这个方法被调用了多次,性能分析工具将告诉我们,在与应用程序交互的这段时间里,调用这个方法所消耗的平均时间。如果其中的一些方法造成了性能瓶颈,我们可以想办法优化一下它们。
调用堆栈 通过追踪某一方法的调用堆栈,我们可以看到应用程序调用该方法的完整路径。
实例数量(对象分配) 有时,我们会发现同一对象被创建了太多次,而我们只需要这一对象的几个实例。在这些情况下,如果只需要一个实例,我们可能考虑使用单件模式;如果需要多个,则应用其他技术来减少对象分配。如果确实需要很多该对象的实例,我们得考虑优化对象本身来降低资源总数以及内存占用量。
对象大小 如果观察到某些对象大小异常,我们可以尝试优化它们以减少其内存占用量。程序中某些对象被多次创建时尤为有效。
垃圾回收 比较性能快照时,我们可能发现一些不再被程序使用的对象仍然在“loitering”,或者存储在内存中。为了避免内存泄漏,我们可以添加一些逻辑,来移除这些对象身上的“残余”引用。
其实目的就一个:优化。 途径有两条:重写占用资源大的环节,完善有问题的环节;前者可以叫内存占用不合理,后者叫内存泄露,囧。
比如在做关于图形化的操作时,例如大量大尺寸的位图交互(碰撞等)所占用的内存以及CPU都是很让人蛋疼的,看我现在摆弄的项目图:
基本上占用内存的几大巨头都是位图了,上面那几个都是人物的动作序列图。
另外这个内存占用的显示数字跟系统任务管理系的内存分析数字是有些出入的,它包含的仅仅是为了保留该类中定义的所有属性,所分配的字节数(每一属性大概需要4字节)。它并不包含:
1、 子对象或字符串占用的内存。
2、 播放器追踪对象所需的内存。每一对象有许多内存控制块没有被计算进来,性能分析工具中也没能显示出所有“display objects”背后的隐藏对象所占用的内存
3、 或者用于处理网络通信或文件访问的内存
4、 浏览器占用的内存
5、 存储Flash Player编码及预定义变量所需的内存
操作系统告诉我们的通常会远大于概要分析所算出的内存。
还有一种测内存的方法,System.totalMemory。算出的值在以上两者之间:
Flash Player 以每4096字节为一个块,将内存从操作系统中划分给小的对象。比如,一个4096字节的块包含了256个16字节的对象,而另一个却包含了16个256字节的对象。
flash.system.System.totalMemory测量从操作系统分配的块的数量以及其他的一些较大的内存分配。它不包括:
1、 操作系统用来显示可视部分、获取事件、处理网络或文件I/O所需的内存。
2、 浏览器占用的内存。
3、 存储Flash Player编码及预定义变量所需的内存。
4、 当Flash Player需要分配第257个16字节数据块的时候,它会从操作系统分配另一个4096字节的块,同时将其预留给16字节的对象
如果不再需要一个块中的所有16字节对象,Flash Player会将该块所占用的内存释放,返给操作系统。
可能会出现这样的情景:分配了上千个16字节对象,但是每256个对象只释放其中的255个,这样的话最终会得到很多块,每个块只包含了 很少的几个16字节对象。
5、 Flash Player不会合并这些对象稀疏的块,这样System.totalMemory以及操作系统告诉我们的将远远大于分析工具显示的,因为大量的系统内存被分配出去却未的到充分的利用。
下面说说内存泄露的情况:
这时你需要制作2个内存快照,用来比对查看那些实例没有被收拾掉,制作第一张快照时,最好在项目的待操作状态,就是个个功能基本加载完毕,用户还没有展开任何操作,所有都是就绪状态,暂时我们先叫A状态。
然后开始个个模块的功能操作,(比如打开每个功能面板,PK,战斗,捕捉,参加其他交互),然后停止操作关闭各个功能模块,回到A状态
(看起来跟A状态相同)此时的状态我们称为B,制作内存快照B。
然后点击“闲置对象”,从打开的试图中我们可以看见闲置对象的概要分析数据:(不截图了,太懒了)
需要说明的是:可能有很多东西泄漏了,但通常是由一到两个根本原因引起的。
最好从祖宗辈对象开始,因为通常它们会包含许多来自子对象的引用,而释放这祖宗对象,同时也能释放其子对象。
具体怎么看这个比照试图,以后有时间在说,开会去了~~