所有应用程序都要管理内存。应用程序的内存管理包括用于确定何时分配内存,分配多少内存,何时将内容放入回收站,以及何时清空回收站的准则。MMgc是 Flash Player用于几乎所有内存分配工作的通用内存管理器。理解MMgc如何管理内存是优化您的代码和您应用程序的性能的一个重要部分。

垃圾收集器自动回收的内存被视为“受管理的内存”。垃圾收集器确定内存何时不再被应用程序使用并回收它。本文分析Flash Player 11和AIR 3中的内存分配、垃圾收集流程和新的pauseForGCIfCollectionImminent()API。

内存分配

Flash Player使用一个页面分配程序(GCheap)来从OD分配大块(几MB)的内存。Gcheap然后将大内存块分解为较小的4K页面,并根据需要将这些页面提供给垃圾收集(GC)内存管理器。


图1. GCHeap从OS分配内存,将它分解为4K的页面,并将这些页面提供给GC。

GC然后使用这些4K页面为系统中不大于2K的对象提供内存。


图2. 4K页面由GC分配给小于2K的对象

对于大于2K的对象(位图、视频、文件等),GCHeap向一个大型的内存分配程序提供一组连续的4K内存块。
当一个大内存块中几乎所有4K页面都分配了时,Flash
Player运行垃圾收集来回收未使用的内存,然后GCHeap尝试从OS分配更多内存。换句话说,垃圾收集仅由内存分配触发。这一事实很重要,在测试和
分析期间一定要记住,因为它意味着空闲应用程序的内存使用从不会改变。

堆和堆栈

堆是分配给在运行时创建或初始化的任何对象的内存。堆上的对象会一直存在到它们被垃圾收集。


图3. 对象A存在于堆上。它由堆栈上的局部变量o引用。(图字:堆栈内存 堆内存)

堆栈是存储在编译时定义的所有变量的内存。堆栈内存以一种顺序方式使用和重用。推送操作将一些内容添加到堆栈顶部。弹出操作从堆栈顶部删除一些内容。访问堆栈中间的内容的唯一方式是删除它上方的所有内容。

局部方法变量、参数和关于在一个方法完成时返回到何处的信息,在方法运行时被推送到堆栈上。对堆栈的更改发生得非常快。对象的堆栈引用可能非常短暂。这些对象引用可能存在于堆栈上,但分配给这些对象的内存来自堆。


图4. 局部变量在定义时被推送到堆栈上。关于在一个方法完成时返回何处的信息也推送到堆栈上。

Flash运行时垃圾收集实现

Flash Player和AIR结合使用延迟的引用计数和保守的标记并清除(mark-and-sweep)方法。

延迟的引用计数

在延迟的引用计数中,堆和堆栈引用之间存在区别。因为堆栈变化很快,并可能包含非常短暂的引用,所以引用计数不会在堆栈引用上执行。而在堆上为引用维护引用计数。


图5. 对象会跟踪它们拥有多少个引用。

堆上的每个对象会跟踪指向它的信息数量。每次您创建一个对象的引用,该对象的引用计数就会递增。当您删除一个引用时,该对象的引用计数会递减。如果对象的
引用计数为0(没有任何信息指向它),它会被添加到零计数表(Zero Count
Table,ZCT)中。当ZCT填满后,就会扫描堆栈以查找任何从堆栈到ZCT上的对象的引用。ZCT上任何没有堆栈引用的对象都会被删除。

延迟引用计数的一个问题是循环引用。如果ObjectA和ObjectB彼此引用,而系统中没有其他对象指向它们,它们将从不会拥有一个零引用计数,因此从不满足使用引用计数进行垃圾收集的资格。这时可以使用“标记并清除”的垃圾收集方法。


图6. Object A和Object B彼此引用,但没有其他引用。

标记/清除

在Flash
Player或AIR中运行的应用程序具有多个GCRoot。您可以将GCRoot视为一个树的一部分,它将应用程序的对象当作树枝。舞台是一个
GCRoot。加载程序是GCRoot。某些菜单是GCRoot。让在供应用程序使用的每个对象可从应用程序内的一个GCRoot访问。GCRoot从不
会被垃圾收集。

应用程序中的每个对象有一个“标记位”。当垃圾收集的标记阶段开始时,所有这些标记位会被清除。MMgc会跟踪应用程序中的所有GCRoot。垃圾收集器
首先从这些根开始,跟踪每个对象并为它到达的每个对象设置标记位。任何不再能够从任何根到达的对象也不再能够从应用程序的任何地方到达——它的标记位不会
在标记阶段设置。收集器完成对它找到的所有对象进行标记之后,就会开始清除阶段。任何没有设置标记位的对象都会被销毁,它的内存会被回收。


图7. 一个循环引用中的对象没有被标记。

图7显示,每个可从Gcroot到达的对象都设置了自己的标记位(蓝色)。一个循环引用中的两个对象(ObjectA和ObjectB)不可从GCRoot到达。它们的标记位将不会设置。因此,即使它们没有零引用计数,这两个对象也会被垃圾收集。

弱引用

Flash Player也可以维持对某些类型的对象的“弱引用”。弱引用是一种对垃圾收集器的正常跟踪过程(跟随所有根来查找可到达的对象的过程)不可见的引用。

当您实例化一个新字典时,可以表明您希望它与字典的键建立较弱的关联。

var dictionary = new Dictionary( true );
d[ someObject ] = someValue;

您也可以在添加事件监听器时,将addEventListener()的函数useWeakReference参数设置为true。

obj.addEventListener( "type", handler, false, 0, true );

在这两种情况下,您都会要求Flash Player在两个对象之间建立引用,但以一种较弱的方式保持该引用。具体来讲,这意味着这个具体的引用在标记期间不会被跟随。


图8. 若引用在标记期间不会被跟踪。

在这种情况下,到Object B的唯一路径是弱的。在跟踪期间将不会经过它,因此Object B不会被标记,并会被收集。但是,如果还有另一个到Object B的强路径,Object B将被标记并被持久化。


图9. 具有强引用的对象将在跟踪期间被找到并标记。

您应该始终清理未使用的引用,从字典删除未使用的项,以及使用removeEventListener()。但是,有时清理未使用的引用不切实际或无法做
到。比如在您的类在您不知情的情况下实例化和销毁时——项渲染器就是通过这种方式使用的。在这些情况下,维持对象的若引用将允许Flash
Player最终删除它们并回收内存。

保守收集

MMgc被视为一种保守的标记/清除收集器。MMgc无法确定内存中的某些值是对象指针(内存地址)还是数字值。为了避免意外地收集值可能指向的对
象,MMgc假设每个值都可以是一个指针。因此,一些没有实际被指向的对象将从不被收集,将被视为一种内存泄漏。尽管您希望最小化内存泄漏以优化性能,但
由保守的GC所导致的偶然泄漏可能是随机的,不会随时间增长,并且对应用程序性能的影响比开发人员导致的泄漏小得多。

增量收集

不幸的是,垃圾收集可导致Flash Player在收集过程完成时定期暂停。这种暂停与应用程序当前运行的内存量成正比。它可能比希望的时间更长,在一些程序中可以察觉到。

标记阶段是垃圾收集过程中最消耗时间的部分。由于此事实,标记过程使用一个动作队列和一个3色算法增量化了。该队列在标记增量之间维护标记状态。

表1. 3色算法

黑色对象已标记,不再位于队列中。

灰色对象位于队列中,还未被标记。

白色对象既未标记也不在队列中。

在标记阶段的开始,所以GCRoot被推送到队列中并变为灰色。


图10. GCRoot在推送到工作队列中时变成灰色。

随着标记过程的继续,标记的对象变为灰色,并从工作队列删除。


图11. 标记的对象是黑色的,不再在工作队列中。

此过程会正常继续进行,直到将一个新对象(白色)添加到一个黑色对象上。当发生此情况时,白色对象从不会设置它的标记位,因为它们的GCRoot已标记。不设置它们的标记位,它们将在清除阶段被垃圾收集。


图12. 新对象被添加到以前标记的对象上。

要预防此问题,可以在MMgc中使用一个白色边界来强制将任何添加到黑色对象上的白色对象立即添加到工作队列中。


图13. 添加到以前标记的对象中的新对象被立即添加到工作队列中。

通过使用工作队列和3色算法,可开始和停止标记阶段来帮助避免长时间、意外的垃圾收集暂停。

迫近度

标记阶段可能是垃圾收集中最耗时的部分,但实际上清空回收站(重新分配空闲内存)也比较耗时。重新分配还可能导致应用程序暂停。垃圾收集器离标记阶段的完成和清除(重新分配)阶段的开始的时间称为“迫近度(imminence)”


图14. 迫近度(图字:标记 暂停、迫近度增长)

public static function pauseForGCIfCollectionImminent(imminence:Number = 0.75):void

是Flash Player 11和AIR 3中的一个新方法,允许您通知垃圾收集器这是完成标记和执行收集的好时机(ActionScript参考文档中的API项)。计划在用户不会注意到时发生可能的暂停,这会带来更好的用户体验。例如,一个游戏可能在游戏中一个级别完成时调用此函数,进而减少在玩游戏期间发生暂停的机会。

您传递给此方法的迫近度值用于与垃圾收集器处于标记阶段中的位置进行比较。如果您传递给它的值比垃圾收集器的迫近度值小,标记和清除将同步完成并导致应用
程序暂停。垃圾收集器必须处于该过程的25%以上,才能响应这个暂停以进行收集的请求。传递一个较小的值(但大于0.25)很可能会强制执行收集,导致应
用程序暂停。传递一个较大的值将告诉垃圾收集器只有在即将暂停时完成收集。

延伸阅读
理解内存管理和垃圾收集在Flash Player和AIR中的工作原理,将有助于您优化您的代码并开发更高性能的应用程序。请查阅Michael Labriola介绍垃圾收集的演示Talking Trash。阅读Christian Cantrell的Providing Hints to the Garbage Collector in AIR 3。您也可以阅读详细的MMgc讨论,其中包含对底层C++代码的描述。

查看原文:Garbage collection internals for Flash Player and Adobe AIR

转:http://bbs.5aser.com/forum.php?mod=viewthread&tid=377

flash GC的更多相关文章

  1. flash性能优化方案整理(最全)

    性能优化的原则 1.避免过早优化:太早优化将使代码难以设计和维护,最好是针对程序的瓶颈进行优化. 2.改进性能有时需要权衡:不能一味注重改进性能,一个项目要考虑各方面的利弊,比如代码的健壮性,结构性, ...

  2. [转]Flash Socket通信的安全策略

    昨天做测试的时候遇到一个问题,做好的SWF在Flash AS3中调试通过,但是发布到html中之后就无法得到数据了.查了一些资料之后找到了解决办法.这里感谢 剑心 提供帮助,以及同事若水三千提供Jav ...

  3. [转] gc tips(3)

    原文地址:http://kevincao.com/2011/08/actionscript-garbage-collection-2/ 谈谈ActionScript垃圾回收(下) 前文我们介绍了GC的 ...

  4. [转] gc tips(1)

    所有应用软件都需要管理内存,一个应用软件的内存管理系统包括了如下准则:什么时候派发内存,要派发多少内存,什么时候把东西放到回收站,以及什么时候清空回收站.MMgc是Flash Player几乎所有内存 ...

  5. Flash Socket通信的安全策略问题 843端口

    1.问题描述       将flash发布为html格式后,加载页面后,swf无法与服务器进行socket通信.Flash端显示的错误为:securityErrorHandler信息: [Securi ...

  6. 大战Java虚拟机【2】—— GC策略

    前言 前面我们已经知道了Java虚拟机所做的事情就是回收那些不用的垃圾,那些不用的对象.那么问题来了,我们如何知道一个对象我们不需要使用了呢?程序在使用的过程中会不断的创建对象,这些所创建的对象指不定 ...

  7. 【转】Flash:同志们,这些知识点你们知道多少?(一些必备的Flash开发知识点)

    1.理解flash的显示列表                2.理解事件冒泡,理解鼠标事件等        3.理解flash的性能瓶颈和大多数影响性能的地方4.理解帧跑道模型,知道timer和ent ...

  8. [转帖]SSD的工作原理、GC和TRIM、写入放大以及性能评测

    SSD的工作原理.GC和TRIM.写入放大以及性能评测 https://blog.csdn.net/scaleqiao/article/details/50511279   SSD的物理结构和工作原理 ...

  9. Flash平台的分析与RIA的趋势

    10月3号,Flash Player 11 和 AIR 3.0正式提供下载,一片安静.最近这两年来,关于Flash的新闻一向是以负面为主,先是 Silverlight 的挑战,然后是 iphone和i ...

随机推荐

  1. Flatpak 1.1.0发布:可终止运行Flatpak实例

    读 Flatpak的Alex Larsson发布了流行的Linux应用程序沙盒和分发框架的新版本,该框架有望成为跨Linux操作系统的应用程序分发的未来. Flatpak 1.1.0现已作为开始推出F ...

  2. Linux 4.20内核得到更新,英特尔CPU 性能降低50%

    根据HKEPC的报道,Linux近日发布了 4.20 内核的一些漏洞修复更新,更新后可能会出现50% 的性能损失,是今年内所有安装Spectre/Meltdown 修补程式中效能跌幅最大的一次. 据报 ...

  3. BZOJ1774[USACO 2009 Dec Gold 2.Cow Toll Paths]——floyd

    题目描述 跟所有人一样,农夫约翰以着宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生 财之道.为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道路行走,都 要向农夫约翰上交过路费 ...

  4. ajax跨域,携带cookie

    解决方案很简单. 直接上代码: web.xml中: 添加了 cors来解决跨域 (奇怪的是,credentials设置为false.反正这个是照搬的...)   <filter>     ...

  5. Json 转 dynamic

    直接上代码: var model = JsonConvert.DeserializeObject<dynamic>("{\"ResponseResult\": ...

  6. (未完成...)Python3网络爬虫(2):利用urllib.urlopen向有道翻译发送数据并获得翻译结果

    环境: 火狐浏览器 pycharm2017.3.3 python3.5 1.url不仅可以是一个字符串,例如:http://www.baidu.com.url也可以是一个Request对象,这就需要我 ...

  7. 【 Gym - 101138K 】 The World of Trains (DP)

    BUPT2017 wintertraining(15) #4E Gym - 101138K 题意 N节车厢的火车,每节车厢容量是1~K,那么有\(K^N\)种火车. 求选择D个连续的且容量相同的车厢的 ...

  8. 2073: [POI2004]PRZ

    2073: [POI2004]PRZ Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 284  Solved: 213[Submit][Status][D ...

  9. SharePoint 2013 批量导入、删除帐号

    删除一个group里所有的帐号: cls ########################### # "Enter the site URL here" $SITEURL = &q ...

  10. 暑期OI大电影——不看后悔整个OI生涯!

    惊爆~!! 2018暑期OI大电影要开始放送啦~!! 各位OI骨灰级大咖登场荧幕~!! 近四十部大电影纷至沓来~!! 著名特级导演CCF.著名特级编剧刘汝佳等纷纷给予高度评价~!! 观众朋友们,OI的 ...