通过编写测试程序发现以下规律,flash内存回收机制的一些特点:
1. 自动内存回收时间不确定。
2. 当一个对象存在被其他对象引用时,这个对象不会被内存回收。
3. 当一个流对象被加载,这个被加载的对象及已经占用了内存。
4. 当一个可视化对象被声明,但没有添加到画面是占用部分内存,加到displayObject上后,占用全部该对象对象全部内存。
5. 当加载重复对象,例如 加载100个同样的 XX.swf ,如果仅是加载,完成后没有引用,那么内存变化规律,波浪型的。如果某个时间内存回收。那么最后留在内存中的应该是大小近似于加载1个 XX.swf (比1个XX.swf 要大些),从此可以推理出,要是不同的东西被加载,那么最后即便是没有内存漏洞,在一定条件下常用的东西内存中可能也会至少保存每一个不同的东西。经我测试好像是这样的。(测多了可能还会有新发现呢)
6. 引用的包括
1) 对对象的存储: 例如 使用一个数组保存 某些对象,那么数组不释放,对象不可能释放
2) 对事件的监听: 例如 监听过程实际上是使用一个对象保存关键字和关键字关联的事件,对事件关键字,查找然后找出对应的关联function。以下是as2代码。As3 的EventDispatcher功能类似
btnListener.click = function() {
trace("haha")
};
bt1.addEventListener("click", btnListener);
使用removerEventer 方法定是要清除掉 处理关键字索引和function 的对象。这样即清除掉了计数引用。
3) 强制回收方式,自动内存回收时间不确定,使用特殊的方法,该方法实际上触发一个错误引起资源回收,使无用的不被计数器引用的都要被回收。(暂时不被使用的,没有引用的那个被自动回收保留的那个一个回收掉)
方法:
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:Error) {
trace(e.message);
}
}
一个例子 假如 有个loader 请求加载url=xxxx.swf 的地址,然后成功加载 xxxx.swf, 10次 ,每次成功后没有处理,假设这时候自动回收没有调用,那么使用强制回收,在debug模式下,会看到回收资源。
[Unload SWF] xxxx.swf ,10个这样的输出。
7. 编写代码注意:
1) 无用的对象,没有引用
2) 降低类设计之间的耦合度,注意对象传递引用的设计等
3) 单例模式,在合适的时候使用
4) 事件循环嵌套造成多次执行,或事件触发循环bug。
5) 对象重复加同样的监听
根据内存特性制作了资源管理类模块
monitor XML 文件
1.客户端根据主配置文件加载 相关模块配置文件,其中之一模块就是monitor xml文件
在编译发布客户端时,可以不包括此文件,在开发人员使用时可以包括此文件,监视客
户端运行情况,那么这样有助于使用更少的类,节省资源。
依赖于XML配置体系的修改,打算客户端重构后实现。
Resource Monitor 资源监视类
资源监视,主要利用弱引用,监视对象是否存在,对象加载的资源大小可以获得,同过对象
是否存在来统计该所有对象资源大小总和。
统计过程中需要对资源类型划分,这里涉及到类型如何划分,以及改造过程中如何传递这
些资源的类型。因为具体改造就是通过一个公用函数获取资源,那么就需要告诉这个函数,
什么地方(模块)用,以便统计。
工作量分布 1编写Resource Monitor类,2修改代码中所有资源加载处。
有一点需要注意,这次添加Resource Monitor类的方式,在以后重构后,加载调用的函数方
式可能都需要改变,设想通过服务来获取资源。那么这个服务的名称等信息自然会得到。
使用方法
weeklyLoader = new Loader();//程序中的loader加载 ,不需要改变
RF.load(weeklyLoader,path,"人物图片");//添加 RF 为资源管理类,采用静态方法访问,path 是资源的url,”人物图片”是模块或资源类型的名称。不需要传递回调方法。