强化内存管理

 在内存管理方面官方的只有两个函数和内存管理直接相关,但是它们都非常有用。下面是一些非官方的补充,当然这并不是唯一方法。

  System.totalMemory

  这是一个简单的工具,但是它灰常重要,因为它是开发者在flash中第一个可以实时应用的工具。它可以让你监听到flash播放器实时的内存占用大小,更重要的是:你可以利用这个来判断是否抛出异常,来终止即将给用户带来的负面体验。

  下面是一个例子:

 

      import flash.system.System;
  import flash.net.navigateToURL;
  import flash.net.URLRequest;
  ...
  // check our memory every 1 second:
  var checkMemoryIntervalID:uint = setInterval(checkMemoryUsage,1000);
  ...
  var showWarning:Boolean = true;
  var warningMemory:uint = 1000*1000*500;
  var abortMemory:uint = 1000*1000*625;
  ...
  function checkMemoryUsage() {
  if (System.totalMemory > warningMemory && showWarning) {
  // show an error to the user warning them that we're running out of memory and might quit
  // try to free up memory if possible
  showWarning = false; // so we don't show an error every second
  } else if (System.totalMemory > abortMemory) {
  // save current user data to an LSO for recovery later?
  abort();
  }
  }
  function abort() {
  // send the user to a page explaining what happpened:
  navigateToURL(new URLRequest("memoryError.html"));
  }

  这一行为可以通过很多方法来实现,但是至少证明了这一行为的目的是好的。

  值得我们注意的是:totalMemory是一个被一个进程(a single process)使用的“全局变量”(shared value),一个进程可能只有一个窗口,或多个浏览窗口,这些取决与浏览器,操作系统或是有多少个窗口被打开。

  弱引用

  在AS3众多的新特性中,我灰常高兴的看到“weak references”。这种引用不会被垃圾收集器作为判定object是 否被回收的依据。它的作用是:如果当一个对象仅仅剩下弱引用时,这个对象将会被垃圾收集器在下一轮回收。但是弱引用只支持两种类型:第一种是经常会因为内 存管理机制带来麻烦的事件监听器,我强烈的建议:每当添加监听器时,都将其第五个参数选项,即弱引用设置为true。下面是其对应的参数设置的例子:

 

      someObj.addEventListener("eventName",listenerFunction,useCapture,priority,weakReference);
  stage.addEventListener(Event.CLICK,handleClick,false,0,true);
  // the reference back to handleClick (and this object) will be weak.

  另一个弱引用支持的是Dictionary object。一般情况下在初始化时设置其第一个参数为true,下面是例子:

 

      var dict:Dictionary = new Dictionary(true);
  dict[myObj] = myOtherObj;
  // the reference to myObj is weak, the reference to myOtherObj is strong

  可以利用弱引用支持Dictionary这个特性,将弱引用“钩”到其他内容上。例如:使用弱引用创建WeakReference 和WeakProxyReference类来实现任何对象都可以创建弱引用。

  WeakReference 类

  WeakReference利用了Dictionary可以存储弱引用的特点来实现将弱引用“钩”到其他任意对象的功能。这个类在实例化和访问 上会有一些开销,所以我建议将其应用在一些可能得不到释放而且较大的对象上。这些代码虽然不能取代那些使对象正常“分解”的代码,但是它可以帮你确保大型 数据对象被垃圾收集器正常分解。

 

      import com.gskinner.utils.WeakReference;
  var dataModelReference:WeakReference;
  function registerModel(data:BigDataObject):void {
  dataModelReference = new WeakReference(data);
  }
  ...
  function doSomething():void {
  // get a local, typed reference to the data:
  var dataModel:BigDataObject = dataModelReference.get() as BigDataObject;
  // call methods, or access properties of the data object:
  dataModel.doSomethingElse();
  }

  从良好的代码结构来说,这是一个好的解决方案,因为它保证了你的数据类型带来良好的安全性,而且没有二义性(non-ambiguou)。这些 代码是那些希望快速实现这一功能的人准备的,我还将其整合到另一个WeakProxyReference类(同时也是一个学习代理(Proxy)的好例子 )中。

  WeakProxyReference 类

  WeakProxyReference 使用了Proxy类来代理弱引用对象。它的效果和WeakReference类是基本是一样的,WeakProxyReference可以直接调用弱引用 对象的方法并且是直接传递给目标。WeakProxyReference的问题就是失去了类型安全性,并且有一点点二义性代码。也就是说它可能会抛出运行 时错误。(特别是当你试图去访问一个对象中不存的属性)但是不会出现编译错误。

 

      import com.gskinner.utils.WeakProxyReference;
  var dataModel:Object; // note that it is untyped, and not named as a reference
  function registerModel(data:BigDataObject):void {
  dataModel = new WeakProxyReference(data);
  }
  function doSomething():void {
  // don't need to get() the referent, you can access members directly on the reference:
  dataModel.doSomethingElse();
  dataModel.length++;
  delete(dataModel.someProperty);
  // if you do need access to the referent, you need to use the weak_proxy_reference namespace:
  var bdo:BigDataObject = dataModel.weak_proxy_reference::get() as BigDataObject;
  }

  一种可以强制执行垃圾收集的方法(不推荐使用)

  在之前,我已提到在AS3中垃圾收集周期是不确定的,没有方法可以知道它下一次什么时候运行。严格的讲这句话也不完全的对,有一个技巧可以强制 让flash播放器执行一次垃圾收集,这个技巧很方便你去探索垃圾收集和在开发期内测试你的程序,但是它绝不能出现在开发完成的产品中,因为它会破坏处理 器的负载能力。同时官方也是不推荐使用的,所以你不能靠它的功能来完成实质功能上提升。

  强制执行垃圾收集(表示计数法或引用清除法),你所要做的就是 执行两次相同的LocalConnection。这样做系统会抛出一个异常,所以你必须为它准备好异常捕捉(try/catch)

 

      try {
  new LocalConnection().connect('foo');
  new LocalConnection().connect('foo');
  } catch (e:*) {}
  // the GC will perform a full mark/sweep on the second call.

  再次重复一次:这个方法仅仅可以用于开发周期内的测试。它绝不能出现在开发完成的产品中!

  总结

  毫无疑问的是:ActionScript3给开发者在资源管理方面带来了更多的工作。虽然我们只有刚刚提到的一些应对工具,但是有对策总是比没 有的好,而且Adobe至少也注意到这个问题了。采取有效的对策和方法并合理的搭配这些工具,相信你可以很好的管理Flash9和Flex2的工程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值