java和flash的垃圾回收都是一个比较热门的话题,今天我也用一个例子来测试下flash的强制垃圾回收。主要用到的而一个类是LocalConnection。

在Flash player的debug版本中提供了gc的方法

Flash Player初始化运行时,会向操作系统申请一大块内存,如果程序很小,有可能根本用不了这么多内存,但FP在开始时不考虑这些,大多数情况下,第一次申请的内存总是不够用的。第一次申请的内存大小,与操作系统、浏览器环境有关。

当Flash Player发现已经申请的内存不够用时,它会再向操作系统申请一大块内存。但在申请之前,请注意,FP会尝试进行垃圾内存回收。那么它是如何回收的呢?
    Flash Player在内部使用懒惰式引用计数回收方案进行垃圾内存回收。

懒惰式指:FP并不会一次把所有可以回收的对象全部回收,它一次仅会回收一部分,如果内存不够用,它会向操作系统申请,如果系统无内存了,它会再次回收,如果全部回收了仍不够用,Game Over!

引用计数指:FP在内部给每个对象标记一个记号,当没有任何对象引用此对象时,它即是可以被回收的;如果一个容器内有许多相互关联的对象,当把这个容器从显示列表中移除,并且置为null后,它也是可以被回收的。

在清楚了FP的内部垃圾回收机制之后,我们可以创建两次没用的LocalConnection,并且连接并不存在的地址,故意抛出异常然后捕获,就强制垃
圾回收,因为,在AS3中LocalConnection是比较占用内存的对象,两次创建该类对象并尝试进行连接的内存开销大小足以请Flash
Player重新向操作系统申请内存,而在申请之前,FP会尝试回收。原理即是这么简单,非独使用LocalConnection可以,其它较耗内存的对
象也可以。

下面是我写的测试代码,主要测试三中情况下内存的使用情况。

  1. package
  2. {
  3. import flash.display.Sprite;
  4. import flash.external.ExternalInterface;
  5. import flash.net.LocalConnection;
  6. public class MemeryGcTest extends Sprite
  7. {
  8. private const num:int = 30000; //子元素个数  根据自己的电脑配置来设置
  9. private var parentContainer:Sprite;//父容器
  10. private var childrenRect:Array;//所有子元素的引用
  11. public function MemeryGcTest(){
  12. init();
  13. }
  14. private function init() : void{
  15. parentContainer=new Sprite();
  16. addChild(parentContainer);
  17. createAllChildrens();
  18. removeAllchildrens();
  19. setChildrenNull();
  20. //doGc();
  21. }
  22. /**
  23. * 移除所有对象
  24. *
  25. */
  26. private function removeAllchildrens():void {
  27. removeAllChildrens( );
  28. removeChild(parentContainer);
  29. }
  30. /**
  31. * 设置不用对象为null 否则不会进行垃圾回收
  32. *
  33. */
  34. private function setChildrenNull():void{
  35. childrenRect = null;
  36. parentContainer = null;
  37. }
  38. /**
  39. * 创建所有子元素
  40. *
  41. */
  42. private function createAllChildrens() : void {
  43. childrenRect=new Array();
  44. for(var i:int = 0;i<num; i++){
  45. var sprite:Sprite=new Sprite();
  46. childrenRect.push(sprite);
  47. sprite.graphics.beginFill(0xff0000);
  48. sprite.graphics.drawRect(0+i/50,0,100,100);
  49. sprite.graphics.endFill();
  50. parentContainer.addChild(sprite);
  51. }
  52. }
  53. /**
  54. * 移除所有子元素
  55. *
  56. */
  57. private function removeAllChildrens():void{
  58. for(var i:int=0;i<num;i++){
  59. parentContainer.removeChild(childrenRect[i]);
  60. delete childrenRect[i];
  61. }
  62. }
  63. /**
  64. * 强制垃圾回收
  65. *
  66. */
  67. private function doGc():void{
  68. try{
  69. var conn1:LocalConnection= new LocalConnection();
  70. conn1.connect("testGc");
  71. var conn2:LocalConnection= new LocalConnection();
  72. conn2.connect("testGc");
  73. }catch(error:Error){
  74. conn1 = null;
  75. conn2 = null;
  76. }
  77. }
  78. }
  79. }

第一种情况,不设置不用元素为null和强制垃圾回收

  1. private function init() : void{
  2. parentContainer=new Sprite();
  3. addChild(parentContainer);
  4. createAllChildrens();
  5. removeAllchildrens();
  6. //setChildrenNull();
  7. //doGc();

测试结果如下:

可以看出占用的内存比较高,点击GC按钮内存依然是“居高不下”。

第二种情况,设置不用元素为null但不强制执行垃圾回收。

  1. private function init() : void{
  2. parentContainer=new Sprite();
  3. addChild(parentContainer);
  4. createAllChildrens();
  5. removeAllchildrens();
  6. setChildrenNull();
  7. //doGc();

测试结果如下:

设置null后虽然刚开始峰值很高,但是Flash Player执行了垃圾回收,很快内存下降到12K。

第三种情况,设置不用对象为null并强制进行垃圾回收。

  1. private function init() : void{
  2. parentContainer=new Sprite();
  3. addChild(parentContainer);
  4. createAllChildrens();
  5. removeAllchildrens();
  6. setChildrenNull();
  7. doGc();

测试结果如下:

可以看出强制垃圾回收确实执行了。

内存泄露举例:
1、引用泄露:对子对象的引用,外部对本对象或子对象的引用都需要置null。
2、系统类泄露:使用了系统类而忘记
做删除操作了,如 BindingUtils.bindSetter(),ChangeWatcher.watch()函数时候完毕后需要调用
ChangeWatcher.unwatch()函数来清除引用 ,否则使用此函数的对象将不会被删除;
类似的还有MUSIC,VIDEO,IMAGE,TIMER,EVENT,BINDING等。
3、效果泄露:当对组件应用效果Effect的时候,当本对象本删除时需要把本对象和子对象上的Effect动画停止掉,然后把Effect的target对象置null; 如果不停止掉动画直接把 Effect置null将不能正常移除对象。
4、SWF泄露:要完全删除一个SWF要调用它的unload()方法并且把对象置null。
5、图片泄露:当Image对象使用完毕后要把source置null。
6、声音、视频泄露: 当不需要一个音乐或视频是需要停止音乐,删除对象,引用置null。

内存泄露解决方法:
1.
在组件的REMOVED_FROM_STAGE事件回掉中做垃圾处理操作(移除所有对外引用(不管是VO还是组件的都需要删除),删除监听器,调用系统类
的清除方法) 先remove再置null, 确保被remove或者removeAll后的对象在外部的引用全部释放干净。
2. 利用Flex的性能优化工具Profile来对项目进程进行监控,可知道历史创建过哪些对象,目前有哪些对象没有被删除,创建的数量,占用的内存比例和用量,创建过程等信息。

总结:关键还是要做好清除工作,自己设置的引用自己要记得删除,自己用过的系统类要记得做好回收处理工作。 以上问题解决的好的话不需要自定义强制回收器也有可能被系统正常的自动回收掉。

flex 强制垃圾回收的更多相关文章

  1. C#或者.NET下的强制垃圾回收办法

    转载 2011年03月16日 17:21:00 标签: c# / .net / button / object / stream / class 8185 今天来谈谈C#的GC,也就是垃圾回收机制,非 ...

  2. 【C# .Net GC】强制垃圾回收 和System GC

    属性 GC.MaxGeneration:获取系统当前支持的最大代数. 方法 GC.GetTotalMemory(bool forceFullCollection) 方法  true表示该方法先做垃圾收 ...

  3. as3中强制垃圾回收

    private function doClearance():void { // trace("clear"); try{ new LocalConnection().connec ...

  4. flex 垃圾回收

    原文在这里:Garbage Collection with Flex and Adobe Air 我终于有时间来整理在flexcamp上演讲的东西并写篇博客了.就在flexcamp前一个月,我几乎天天 ...

  5. Java的垃圾回收机制:强制回收System.gc() Runtime.getTime().gc()

    垃圾回收 当引用类型的实体,如对象.数组等不再被任何变量引用的时候.这块占用的内存就成为了垃圾.JVM会根据自己的策略决定是回收内存 注意: 垃圾回收只回收内存中的对象,无法回收物理资源(数据库连接, ...

  6. .NET垃圾回收 – 原理浅析

    在开发.NET程序过程中,由于CLR中的垃圾回收(garbage collection)机制会管理已分配的对象,所以程序员就可以不用关注对象什么时候释放内存空间了.但是,了解垃圾回收机制还是很有必要的 ...

  7. .NET垃圾回收:非托管资源,IDispose和析构函数的结合

    http://blog.jobbole.com/85436/ 原文出处: 田小计划   欢迎分享原创到伯乐头条 前面一篇文章介绍了垃圾回收的基本工作原理,垃圾回收器并不是可以管理内存中的所有资源.对于 ...

  8. c# -- 对象销毁和垃圾回收

    有些对象需要显示地销毁代码来释放资源,比如打开的文件资源,锁,操作系统句柄和非托管对象.在.NET中,这就是所谓的对象销毁,它通过IDisposal接口来实现.不再使用的对象所占用的内存管理,必须在某 ...

  9. java 之 对象与垃圾回收

    1.垃圾回收机制只负责回收堆内存中的对象,不会回收任何物理资源(如数据库连接,网络IO等资源) 2.程序无法精确控制垃圾回收的运行,垃圾回收会在合适的时候运行.当对象永久的失去引用后,系统会在合适的时 ...

随机推荐

  1. js的抖动及防抖和节流

     js的抖动 在 js 中 改变窗口大小 & 上下滚动滚动条 & 反复向输入框中输入内容 ... , 如果绑定了相应的事件 , 这些事件的触发频率非常高, 严重影响用户体验和服务器的性 ...

  2. Filter&Listener笔记

    ## 今日内容     1. Filter:过滤器     2. Listener:监听器 # Filter:过滤器     1. 概念:         * 生活中的过滤器:净水器,空气净化器,土匪 ...

  3. JavaScript的循环结构和经典题目

    一.JS中的循环结构 循环结构的执行步骤1.声明循环变量:2.判断循环条件;3.执行循环体操作:4.更新循环变量:5.然后循环执行2-4,直到条件不成立,跳出循环. while循环()中的表达式,运算 ...

  4. Java httpClint实现文件上传

    Maven依赖 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId&g ...

  5. 34. Find First and Last Position of Element in Sorted Array (JAVA)

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

  6. 出现( linker command failed with exit code 1)错误总结(http://blog.csdn.net/hengshujiyi/article/details/21182813)

    这种问题,通常出现在添加第三方库文件或者多人开发时. 这种问题一般是找不到文件而导致的链接错误. 我们可以从如下几个方面着手排查. 1.以如下错误为例,如果是多人开发,你同步完成后发现出现如下的错误. ...

  7. sklearn逻辑回归库函数直接拟合数据

    from sklearn import model_selection from sklearn.linear_model import LogisticRegression from sklearn ...

  8. 基于FPGA的以太网开发

    基于FPGA的以太网开发,在调试过的FPGA玩家开来,其实算不上很难的技术!但是如果只是菜鸟级别的选手,没有调试过的话,就有些头疼了!早在自己在实习的时候,就接触到XAUI(万兆以太网口)接口,但是由 ...

  9. Linux下用命令查看CPU ID以及厂家等信息

    Linux下用命令查看CPU ID // 获得CPU IDdmidecode -t 4 | grep ID |sort -u |awk -F': ' '{print $2}' // 获得磁盘IDfdi ...

  10. Linux 正在尝试其他镜像

    Linux  正在尝试其他镜像 发生情景: 在windows7系统,安装了虚拟机Oracle VM VirtualBox,使用的CentOS7, 在使用yum的使用,一直提醒"正在尝试其他镜 ...