加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

《AS3 Expert》_15 Flash Player的垃圾内存回收机制:能否强制回

发布时间:2020-12-15 18:26:44 所属栏目:百科 来源:网络整理
导读:原文: http://flash006.com/230 在Adobe Flash Player 10中,AS3的内部垃圾回收机制是怎样的?程序员可以强制FP回收内存吗?答案是否定的,但有方法。 1. 毛主席请猫吃辣椒的故事 建国初期,国家正在对资本主义工商业进行社会主义改造,毛泽东问周恩来、刘
原文: http://flash006.com/230


在Adobe Flash Player 10中,AS3的内部垃圾回收机制是怎样的?程序员可以强制FP回收内存吗?答案是否定的,但有方法。

1. 毛主席请猫吃辣椒的故事

建国初期,国家正在对资本主义工商业进行社会主义改造,毛泽东问周恩来、刘少奇等,如何才能让猫吃辣椒?刘说,把猫逮住,用筷子捅下去。周说,先把猫饿上三天,然后把辣椒裹在肉里给它吃。毛都不赞成这两种做法,毛说,把辣椒抹在猫屁股上,猫觉得辣自然就去会舔,而且还会因为这样做而兴奋不已。
2. 强制垃圾内存回收的代码

AS3程序员没有办法强制Flash Player进行垃圾回收,但有一种类似于毛主席请猫吃辣椒的方法可以使用。
MoonSpirit在天地会撰写过一篇关于强制垃圾回收的文章: [as hack技术]垃圾回收机强制执行。文中例证,使用LocalConnection连接非法地址,并捕获导常,可以强制进行垃圾回收。 sban在MoonSpirit的基础上,简单修改了一下代码,如下:
  1. package {
  2. import flash.display.Bitmap;
  3. import flash.display.BitmapData;
  4. import flash.display.Sprite;
  5. import flash.net.LocalConnection;

  6. /**
  7. *
  8. * @author sban http://sban.biz/
  9. * 修改自MoonSpirit的强制垃圾回收测试代码
  10. */
  11. public class GarbageCollectionTest extends Sprite {
  12. private const SQR_AMOUNT : int = 10000; //方块数量
  13. private var _container_sp : Sprite;//容器sprite
  14. private var _sqrList: Array;//所有方块的引用

  15. //强制垃圾回收使用的对象
  16. private var conn1 :LocalConnection;
  17. private var conn2 :LocalConnection;

  18. public function GarbageCollectionTest() {
  19. init( );
  20. }

  21. private function init( ) : void{
  22. _container_sp = new Sprite( );
  23. addChild(_container_sp);
  24. //initNoBitmapDataView( );//峰值4111K,手动回收两次变为9K
  25. initBitmapDataView( );//峰值14K,最小为14K,手动回收基本无变化
  26. }

  27. //初始化 通过通常手段 显示
  28. private function initNoBitmapDataView( ) : void {
  29. layoutTenThousandSqr( );

  30. unLayoutTenThousandSqr( );
  31. _sqrList = null;
  32. removeChild(_container_sp);
  33. _container_sp = null;
  34. }

  35. //初始化 通过BitmapData快照 显示
  36. private function initBitmapDataView( ) : void {
  37. layoutTenThousandSqr( );

  38. unLayoutTenThousandSqr( );
  39. _sqrList = null;
  40. removeChild(_container_sp);
  41. _container_sp = null;

  42. doClearance( );
  43. }

  44. private function layoutTenThousandSqr( ) : void {
  45. _sqrList = new Array( );
  46. for(var i : int = 0; i < SQR_AMOUNT; i++){
  47. _sqrList.push(new Sprite());
  48. _sqrList[i].graphics.beginFill(0xff0000);
  49. _sqrList[i].graphics.drawRect(0,100,100);
  50. _sqrList[i].graphics.endFill();
  51. _container_sp.addChild(_sqrList[i]);
  52. }
  53. }

  54. //不显示
  55. private function unLayoutTenThousandSqr( ) : void {
  56. for(var i : int = 0; i < SQR_AMOUNT; i++){
  57. _container_sp.removeChild(_sqrList[i]);
  58. delete _sqrList[i];
  59. }
  60. }

  61. //精髓,垃圾回收机强制调用
  62. private function doClearance( ) : void {
  63. trace("clear");
  64. try{
  65. conn1 = new LocalConnection();
  66. conn1.connect("sban garbage collection 1");
  67. conn2 = new LocalConnection();
  68. conn2.connect("sban garbage collection 1");
  69. }catch(e :*){}
  70. finally{
  71. conn1 = null;
  72. conn2 = null;
  73. }
  74. }
  75. }
  76. }
复制代码
首先sban不调用doClearance方法,手动单击 两次FB的“运行垃圾回收器”按钮(为什么要两次,后面解答),内存二下从4111K降到了9K!如下图所示,雷人吧。


然后呢,sban调用doClearance方法,这次无论是否手动回收,内存占用无变化,如下图所示,这说明doClearance方法已经强制了垃圾内存回收,它作用了!


那么,为什么创建两次没用的LocalConnection可以强制回收内存呢?

3. AS3垃圾内存回收机制

在Flash Player初始化运行时,会向操作系统申请一大块内存,如果程序很小,有可能根本用不了这么多内存,但FP在开始时不考虑这些,大多数情况下,第一次申请的内存总是不够用的。第一次申请的内存大小,与操作系统、浏览器环境有关。
当Flash Player发现已经申请的内存不够用时,它会再向操作系统申请一大块内存。但在申请之前,请注意,FP会尝试进行垃圾内存回收。那么它是如何回收的呢?
Flash Player在内部使用 懒惰式引用计数回收方案进行垃圾内存回收, 懒惰式指:FP并不会一次把所有可以回收的对象全部回收,它一次仅会回收一部分,如果内存不够用,它会向操作系统申请,如果系统无内存了,它会再次回收,如果全部回收了仍不够用,Game Over! 引用计数指:FP在内部给每个对象标记一个记号,当没有任何对象引用此对象时,它即是可以被回收的;如果一个容器内有许多相互关联的对象,当把这个容器从显示列表中移除,并且置为null后,它也是可以被回收的。
在小节2中, sban问到为什么要手动单击两次“运行垃圾回收器”按钮,这是由于FP垃圾回收机制的 懒惰性造成的。
在清楚了FP的内部垃圾回收机制之后,我们便可以回答,为什么创建两次没用的LocalConnection,并且连接并不存在的地址,故意抛出异常然后捕获,可以强制垃圾回收呢?因为,在AS3中LocalConnection是比较占用内存的对象,两次创建该类对象并尝试进行连接的内存开销大小足以请Flash Player重新向操作系统申请内存,而在申请之前,FP会尝试回收。原理即是这么简单,非独使用LocalConnection可以,其它较耗内存的对象也可以。

本文属于《 ActionScript 3.0中高级编程话题 》的一部分,转载请注明 作者 及出处,非商用。

1,如何访问不可访问的东东?(数组访问操作符的三个功能)

2,FB与FD同时存在的一个bug(代码智能提示的隐匿陷阱)

3,为什么for不能有序遍历数组的所有元素?(Array的设计原理)

4,every,some,map,forEach,filter(Array的五个实用方法)

5,如何让if语言写的更简洁?(七种布尔转换为假的情况总结)

6,在AS3中,如何实现数组及对象的深拷贝?

7,AS3中的八种基元类型

8,AS3中的一些基本定义,Function与Method的区别

9,像Ruby一样简易行码:使用Prototype扩展原生对象

10,动态语言的基石:函数闭包

11,Traits对象:为什么静态方法不能被继承

12,变量及作用域

13,命名空间:如何控制未知方法的调用

14,E4X用法简要

15,Flash Player的垃圾内存回收机制:能否强制回收?

16,AS3事件机制概述

17,不定参数(rest parameters)的二次传递

18,跳桢

19,在AS3中属性的访问原理

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读