as3.0垃圾回收机制

合集下载

as3

as3

1、as2与as3.的最主要区别是什么?2、as3.0垃圾回收器是如何工作的3、flex和后台语言是如何交互的?4、请说下你理解AS3的事件机制是什么机制?你认为正确的就可以说出来?5、请问addEventListener有几个参数,说明各个参数的含义6、请问你知道loader,URLLoader,URLStream这个三种动态加载资源的具体使用场合,以及有什么区别7、有三种基本数字类型:number, int, 和uint 请问有什么区别.具体说一下.8、请问undefined 、null和NaN是否一样,如果不一样能否说出其中的区别呢?9、请问AS与JS通讯,应该怎样实现?10、请问在清除对象时,哪些情况会因该对象可达而导致其无法清除11、请问自定义事件怎样实现,请写出具体的实现方式。

12、请问帧监听与Timer监听有什么区别?在极端情况(性能消耗严重)下,怎样精确的保证1秒间隔监听13、请问用什么办法解决安全域的问题?如果你不知道安全域的问题的话,可以在本机中绑定一下图片,然后再放到服务器上,就会出现此问题了.14、Math.round( ),Math.floor( ) 和Math.ceil( ) 三个方法都是四舍五入,请问有什么区别?15、如果发生内存泄露,你是如何解决的?16、flash与flex是如何协调开发的?17、使用Flex Bulider3如何跟踪程序?18、as3怎样连接数据库??19、什么是游戏引擎和对他的认识20、substring( ),substr( ), slice(),请说下3种解析字符串的不同之处,以及适用场合?21、AS3 中有那些基本数据类型?有那些复杂数据类型?他们的默认值是什么?22、怎么样转换数组为字符串,怎么样将字符串转化为数组?23、什么是OOP?OOP有那些特征简要说明?24、谈谈你对面向对象的理解25、谈谈对A*寻路算法的理解26、如何把MouseEvent 的localX 和localY 属性转化成全局坐标?27、请问知道层级的概念嘛?如果知道请问怎么样交换2个组件的层级呢?28、请问Flash重绘机制是怎样的?如何保证尽量少的大规模重绘?29、请问在移动位图和矢量图的过程中,两者在消耗CPU方面的差异。

JVM系列(二):JVM的4种垃圾回收算法、垃圾回收机制与总结

JVM系列(二):JVM的4种垃圾回收算法、垃圾回收机制与总结

垃圾回收算法1.标记清除标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。

在标记阶段首先通过根节点(GC Roots),标记所有从根节点开始的对象,未被标记的对象就是未被引用的垃圾对象。

然后,在清除阶段,清除所有未被标记的对象。

适用场合:●存活对象较多的情况下比较高效●适用于年老代(即旧生代)缺点:●容易产生内存碎片,再来一个比较大的对象时(典型情况:该对象的大小大于空闲表中的每一块儿大小但是小于其中两块儿的和),会提前触发垃圾回收●扫描了整个空间两次(第一次:标记存活对象;第二次:清除没有标记的对象)2.复制算法从根集合节点进行扫描,标记出所有的存活对象,并将这些存活的对象复制到一块儿新的内存(图中下边的那一块儿内存)上去,之后将原来的那一块儿内存(图中上边的那一块儿内存)全部回收掉现在的商业虚拟机都采用这种收集算法来回收新生代。

适用场合:●存活对象较少的情况下比较高效●扫描了整个空间一次(标记存活对象并复制移动)●适用于年轻代(即新生代):基本上98%的对象是”朝生夕死”的,存活下来的会很少缺点:●需要一块儿空的内存空间●需要复制移动对象3.标记整理复制算法的高效性是建立在存活对象少、垃圾对象多的前提下的。

这种情况在新生代经常发生,但是在老年代更常见的情况是大部分对象都是存活对象。

如果依然使用复制算法,由于存活的对象较多,复制的成本也将很高。

标记-压缩算法是一种老年代的回收算法,它在标记-清除算法的基础上做了一些优化。

首先也需要从根节点开始对所有可达对象做一次标记,但之后,它并不简单地清理未标记的对象,而是将所有的存活对象压缩到内存的一端。

之后,清理边界外所有的空间。

这种方法既避免了碎片的产生,又不需要两块相同的内存空间,因此,其性价比比较高。

4.分代收集算法分代收集算法就是目前虚拟机使用的回收算法,它解决了标记整理不适用于老年代的问题,将内存分为各个年代。

一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),在堆区之外还有一个代就是永久代(Permanet Generation)。

Java中的垃圾回收机制是如何工作的

Java中的垃圾回收机制是如何工作的

Java中的垃圾回收机制是如何工作的在 Java 编程的世界里,垃圾回收机制是一项至关重要的特性,它就像是一位默默工作的“清洁工”,负责自动管理内存的分配和释放,让开发者能够更专注于业务逻辑的实现,而不必过度操心内存管理的繁琐细节。

要理解 Java 中的垃圾回收机制是如何工作的,首先得明白什么是垃圾。

在 Java 中,当一个对象不再被任何引用所指向,也就是没有任何途径能够访问到它时,这个对象就被视为垃圾。

想象一下,一个对象就像是一个房间,如果没有钥匙能打开这个房间的门,那么这个房间里的东西也就没有用了,它就变成了垃圾。

那么,Java 是如何发现这些垃圾对象的呢?这主要通过两种方式:引用计数法和可达性分析算法。

引用计数法的原理比较简单直观。

给每个对象添加一个引用计数器,每当有一个地方引用这个对象时,计数器就加 1;当引用失效时,计数器就减 1。

当计数器的值为 0 时,就表明这个对象没有被引用,可以被当作垃圾回收。

然而,这种方法存在一个问题,那就是无法解决循环引用的情况。

比如对象 A 引用了对象 B,对象 B 又引用了对象 A,但除此之外没有其他地方引用它们,按照引用计数法,它们的计数器都不为 0,但实际上它们已经不再被使用了,是应该被回收的垃圾。

相比之下,可达性分析算法就更强大和准确。

它从一些被称为“GC Roots”的对象出发,沿着引用链向下搜索。

如果一个对象不能从任何“GC Roots”对象通过引用链到达,那么这个对象就被认为是不可达的,是垃圾。

“GC Roots”对象通常包括虚拟机栈(栈帧中的本地变量表)中引用的对象、方法区中类静态属性引用的对象、方法区中常量引用的对象以及本地方法栈中 JNI(即 Java Native Interface)引用的对象。

当垃圾回收器确定了哪些对象是垃圾之后,就会开始进行回收操作。

Java 的垃圾回收算法主要有标记清除算法、复制算法、标记压缩算法以及分代收集算法。

Python中的垃圾回收机制

Python中的垃圾回收机制

Python是一种高级编程语言,被广泛应用于各个领域的软件开发中。

与许多其他编程语言不同,Python内置了自动垃圾回收机制,使得开发者能够更加专注于业务逻辑,而无需过多关注内存管理的细节。

本文将深入探讨Python中的垃圾回收机制,并解释其原理和工作方式。

在传统的编程语言中,开发者需要手动管理内存分配和释放。

过多的内存分配或未正确释放的内存会导致内存泄漏,从而导致应用程序的性能下降甚至崩溃。

为了避免这些问题,Python引入了垃圾回收机制。

垃圾回收是一种自动管理内存的技术,通过识别并清除不再使用的内存块,使得这些内存块可以被重新使用。

Python中的垃圾回收机制是基于引用计数的。

每个对象都有一个引用计数器,记录指向该对象的引用数量。

当一个对象的引用计数器变为零时,说明该对象不再被使用,垃圾回收机制将会回收该对象占用的内存空间。

Python的垃圾回收机制使用了两种策略,一种是引用计数,另一种是循环垃圾收集。

引用计数策略非常高效,可以在对象的引用计数器变为零的时候立即回收该对象。

然而,引用计数策略并不能处理循环引用的情况。

循环垃圾收集机制通过检查对象之间的引用关系,来判断对象是否可以被回收。

如果一个对象不再被其他对象引用,并且没有引用其他对象,那么该对象将会被回收。

循环垃圾收集机制使用了标记-清除算法,它通过标记可达的对象,然后清除未被标记的对象,最后回收这些未被标记的对象所占用的内存空间。

除了引用计数和循环垃圾收集之外,Python还引入了分代回收机制。

这是因为不同对象的生命周期是不同的,有些对象可能会存活更长时间,而有些对象可能只存活很短的时间。

分代回收机制将所有对象分为不同的代,根据对象的存活时间选择适当的回收策略。

常见的分代回收有三代,分别是0代、1代和2代。

0代包含了最新创建的对象,而2代包含了存活时间最长的对象。

垃圾回收机制会根据不同的代执行不同的回收算法,以提高垃圾回收的效率。

在Python中,垃圾回收机制是自动启动的,并且无法手动触发。

AS垃圾回收

AS垃圾回收
一、Flash Player垃圾回收机制:
Flash Player垃圾回收工作是由垃圾回收器(garbage collector)完成的。垃圾回收器是运行在后台的一个进程,它释放那些不再被应用所使用对象所占用的内存。不再被应用所使用的对象是指那些不再会被那些活动着(工作着)的对象所“引用”的对象。在AS中,对于非基本类型(Boolean, String, Number, uint, int)的对象,在对象之间传递的都是对象引用,而不是对象本身。删除一个变量只是删除了对象的引用,而不是删除对象本身。一个对象可以被多处引用,通过这些不同的引用所操作的都是同一个对象。
二、开发中导致内存泄露的常见情况
通过上面的讨论我们可以知道,只要对象被其他活动对象(仍在运行的)所引用,那么这个对象就不会被垃圾回收,从而可能造成内存泄露。
在我们的开发中,如下的一些情形会导致内存泄露:
(一)被全局对象所引用的对象在它们不再使用时,开发者忘记从全局对象上清除对它们的引用就会产生内存泄露。常见的全局对象有stage,主 Application,类的静态成员以及采用singleton模式创建的实例等。如果使用第三方框架,比如:PureMvc,Cairongorm 等,要注意这些框架的实现原理,尤其要注意框架里面采用singleton模式创建的controler和Model。
删除。例如:
var a:Object = {foo:"bar"}
// 现在对象的引用计数为1(a)
var b:Object = a;
// 现在对象的引用计数为2(a和b)
delete(a);
// 对象的引用计数又回到了1 (b)
delete(b);
// 对象的引用计数变成0,现在,这个对象可以被GC释放内存。

JVM垃圾回收机制

JVM垃圾回收机制

JVM垃圾回收机制每个Java程序员迟早都会碰到下⾯这个错误:ng.OutOfMemoryError这个时候⼀般会建议采⽤如下⽅式解决这个错误:增加MaxPermSize值增加最⼤堆内存到512M(-xmx参数)这篇⽂章会具体介绍Java堆空间和参数MaxPermSize的含义。

这篇⽂章涉及下列主题,并采⽤Hotspot JVM:垃圾回收器(Garbage Collector,GC)哪个JVM命令⾏选项垃圾回收器垃圾回收器负责:分配内存保证所有正在被引⽤的对象还存在于内存中回收执⾏代码已经不再引⽤的对象所占的内存应⽤执⾏时,定位和回收垃圾对象的过程会占⽤总执⾏时间的将近25%,这会拖累应⽤的执⾏效率。

Hotspot VM提供的垃圾回收器是⼀个分代垃圾回收器(Generational GC)[9,16,18]-将内存划分为不同的阶段,也就是说,不同的⽣命周期的对象放置在不同的地址池中。

这样的设计是基于弱年代假设(Weak Generational Hypothesis):1.越早分配的对象越容易失效;2.⽼对象很少会引⽤新对象。

这种分代⽅式可以减少垃圾回收的停顿时间以及⼤范围对象的回收成本。

Hotspot VM将其堆空间分为三个分代空间:1. 年轻代(Young Generation)○ Java应⽤在分配Java对象时,这些对象会被分配到年轻代堆空间中去○这个空间⼤多是⼩对象并且会被频繁回收○由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率2. 年⽼代(Old Generationn)○年轻代堆空间的长期存活对象会转移到(也许是永久性转移)年⽼代堆空间○这个堆空间通常⽐年轻代的堆空间⼤,并且其空间增长速度较缓○由于⼤部分JVM堆空间都分配给了年⽼代,因此其垃圾回收算法需要更节省空间,此算法需要能够处理低垃圾密度的堆空间3. 持久代(Permanent Generation)○存放VM和Java类的元数据(metadata),以及interned字符串和类的静态变量次收集(Minor GC)和全收集(Full GC)当这三个分代的堆空间⽐较紧张或者没有⾜够的空间来为新到的请求分配的时候,垃圾回收机制就会起作⽤。

Python的垃圾回收机制(引用计数+标记清除+分代回收)

Python的垃圾回收机制(引⽤计数+标记清除+分代回收)⼀、写在前⾯:我们都知道Python⼀种⾯向对象的脚本语⾔,对象是Python中⾮常重要的⼀个概念。

在Python中数字是对象,字符串是对象,任何事物都是对象,⽽它们的核⼼就是⼀个结构体--PyObject。

typedef struct_object{ int ob_refcnt; struct_typeobject *ob_type;}PyObject;PyObject是每个对象必有的内容,其中ob_refcnt就是做为引⽤计数。

⼆、垃圾回收机制垃圾回收(Garbage Collection)⼤家应该多多少少都听过,但是什么是垃圾回收呢?我们这⾥说的垃圾回收肯定不是把垃圾丢进垃圾桶。

现在的⾼级语⾔Java,C#等,都采⽤了垃圾回收机制,⽽不再是C,C++⾥⽤户⾃⼰管理维护内存的⽅式,⾃⼰管理内存是很⾃由,但是可能出现内存泄漏,悬空指针等问题。

⽽垃圾回收机制作为现代编程语⾔的⾃动内存管理机制,专注于两件事:1. 找到内存中⽆⽤的垃圾资源 2. 清除这些垃圾并把内存让出来给其他对象使⽤。

三、Python中的垃圾回收在Python中,垃圾回收机制主要是以引⽤计数为主要⼿段,以标记清除和分代回收机制作为辅助⼿段实现的。

1、引⽤计数通过前⾯的介绍,我们已经知道PyObject是每个对象必有的内容,⽽当⼀个对象有新的引⽤时,它的ob_refcnt就会增加,当引⽤它的对象被删除,它的ob_refcnt就会减少,当引⽤计数为0时,该对象⽣命就结束了。

我们来看看引⽤计数+1的情况有什么:(1)对象被创建:这⾥实际上123这个对象并没有在内存中新建,因为在Python启动解释器的时候会创建⼀个⼩整数池,在-5~256之间的整数对象会被⾃动加载到内存中等待调⽤。

因此a=123是对123这个整数对象增加了⼀次引⽤。

⽽456是不在整数池⾥的,需要创建对象,那么最后的引⽤次数是2呢?因为sys.getrefcount(b)也是⼀次引⽤。

AS3-内存回收机制

AS3 内存回收机制一、AS3 内存回收机制 (1)二、AS3 内存回收机制 (2)三、AS3强制内存回收方法之二 (4)四、AS3 释放内存 (7)五、AS3中的内存泄露与垃圾回收 (8)六、AS3 内存释放优化原则 (10)七、as3 内存回收机制测试 (10)八、AS3内存优化13条 (13)九、AS3的垃圾回收机制详解 (14)十、flash as3 内存管理和资源管理 (18)十一、轻松几行让你AS3程序不再“内存泄露 (18)注意:本资源多半来源于互联网sword收集一、AS3 内存回收机制1.什么是垃圾回收器垃圾收集器是一个后台进程它负责回收程序中不再使用的对象占用的内存。

非活动对象就是不再有任何其他活动对象引用它。

为便于理解这个概念,有一点非常重要,就是要意识到除了非原生类型(Boolean, String, Number, uint, int 除外),你总是通过一个句柄访问对象,而非对象本身。

当你删除一个变量其实就是删除一个引用,而非对象本身。

2.as中内存机制的方法首先是引用计数法:引用计数法是一种用于跟踪活动对象的较为简单的方法,当你创建一个指向某个对象的引用,该对象的引用计数器加1;当你删除该对象的一个引用,该计数器减1.当某对象的计数器变成0,该对象将被标记以便垃圾回收器回收。

var a:MovlieClip = new MovieClip();addChild(a); // a的引用计数器为1var b:MovieClip = a;//a的引用计数器为2addChild(b);removeChild(a);a = null;//a的引用计数器为1removeChild(b);b = null; //a的引用计数器为0其次是标志清除法:清除法查找非活动对象。

FlashPlayer从你的应用程序根对象开始(ActionScript3.0中简称为root)直到程序中的每一个引用,都为引用的对象做标记。

深度解析Python垃圾回收机制(超级详细)

深度解析Python垃圾回收机制(超级详细)我们知道,⽬前的计算机都采⽤的是图灵机架构,其本质就是⽤⼀条⽆限长的纸带,对应今天的存储器。

随后在⼯程学的推演中,逐渐出现了寄存器、易失性存储器(内存)以及永久性存储器(硬盘)等产品。

由于不同的存储器,其速度越快,单位价格也就越昂贵,因此,妥善利⽤好每⼀⼨告诉存储器的空间,永远是系统设计的⼀个核⼼。

程序在运⾏时,需要在内存中开辟出⼀块空间,⽤于存放运⾏时产⽣的临时变量,计算完成后,再将结果输出到永久性存储器中。

但是当数据量过⼤,或者内存空间管理不善,就很容易出现内存溢出的情况,程序可能会被操作系统终⽌。

⽽对于服务器这种⽤于永不中断的系统来说,内存管理就显得更为重要了,不然很容易引发内存泄漏。

这⾥的内存泄漏是指程序本⾝没有设计好,导致程序未能释放已不再使⽤的内存,或者直接失去了对某段内存的控制,造成了内存的浪费。

那么,对于不会再⽤到的内存空间,Python 是通过什么机制来管理的呢?其实在前⾯章节已⼤致接触过,就是引⽤计数机制。

Python引⽤计数机制在学习 Python 的整个过程中,我们⼀直在强调,Python 中⼀切皆对象,也就是说,在 Python 中你⽤到的⼀切变量,本质上都是类对象。

那么,如何知道⼀个对象永远都不能再使⽤了呢?很简单,就是当这个对象的引⽤计数值为 0 时,说明这个对象永不再⽤,⾃然它就变成了垃圾,需要被回收。

举个例⼦:import osimport psutil# 显⽰当前 python 程序占⽤的内存⼤⼩def show_memory_info(hint):pid = os.getpid()p = psutil.Process(pid)info = p.memory_full_info()memory = s / 1024. / 1024print('{} memory used: {} MB'.format(hint, memory))def func():show_memory_info('initial')a = [i for i in range(10000000)]show_memory_info('after a created')func()show_memory_info('finished')输出结果为:initial memory used: 47.19140625 MBafter a created memory used: 433.91015625 MBfinished memory used: 48.109375 MB注意,运⾏此程序之前,需安装 psutil 模块(获取系统信息的模块),可使⽤ pip 命令直接安装,执⾏命令为 $pip install psutil,如果遇到Permission denied 安装失败,请加上 sudo 重试。

AS3面试题

AS3面试题1.请问你知道loader,URLLoader,URLStream这个三种动态加载资源的具体使用场合,以及有什么区别2.如何把MouseEvent 的localX 和localY 属性转化成全局坐标?3.请问condenseWhite 这个属性在TextInput里是表示什么意思?4.我想获取系统里的字体,请问怎么办?5.substring( ),substr( ), slice(),请说下3种解析字符串的不同之处,以及适用场合?6.FileReference 请说下此对象的几个相关事件7.as2与as3.的最主要区别是什么?8.as3.0垃圾回收器是如何工作的9.flex和后台语言是如何交互的?10.请说下你理解AS3的事件机制是什么机制?你认为正确的就可以说出来?11.请问a ddEventListener里面有几个参数,你能说出具体的使用方法?12.请问undefined 和null 是否一样,如果不一样能否说出其中的区别呢?13.有三种基本数字类型:number, int, 和uint 请问有什么区别.具体说一下.14.请问一个数组里可以放不同的类型嘛?1、请问你知道loader,URLLoader,URLStream这个三种动态加载资源的具体使用场合,以及有什么区别嘛?答案(1) LoaderLoader 类可用于加载SWF 文件或图像(JPG、PNG 或GIF)文件。

使用load() 方法来启动加载。

被加载的显示对象将作为Loader 对象的子级添加。

(2) URLLoaderURLLoader 类以文本、二进制数据或URL 编码变量的形式从URL 下载数据。

在下载文本文件、XML 或其它用于动态数据驱动应用程序的信息时,它很有用。

URLLoader 对象会先从URL 中下载所有数据,然后才将数据用于ActionScript。

它会发出有关下载进度的通知,通过bytesLoaded 和bytesT otal 属性以及已调度的事件,可以监视下载进度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ActionScript 3.0 垃圾回收的辅助方法2011-11-01 16:56package org.managers{import .LocalConnection;import flash.system.System;public class GCManager{/*** 多少秒回收一次*/private static const INTERVALSECOND:int = 300;private static var per:int = 0;public static function start():void{TimerManager.attachTimer(timerHandler);}public static function stop():void{TimerManager.detachTimer(timerHandler);}private static function timerHandler():void{if(per<INTERVALSECOND){per++;return;}per = 0;//回收内存try{//System.gc();var lc1: LocalConnection = new LocalConnection(); var lc2:LocalConnection = new LocalConnection(); lc1.connect( "gcConnection" );lc2.connect( "gcConnection" );}catch (e:Error){}}}}以上代码,看不出来吧?正常,这是种辅助方式让Flash封装的,不对外开放的GC强制去回收一次垃圾。

但不稳定。

Flex的垃圾回收机理及预防内存泄露本文链接:/wwwanq/blog/item/82932022cee9f346935807ea.html本文主要通过对互联网上的一些资料进行收集和整理,然后结合自己做的一些试验写出,未必全面准确,欢迎改正或者补充。

内存问题一直是程序员比较关心的问题,每个程序员都希望自己开发的程序足够健壮,在运行过程中不会因内存泄露而导致程序运行变慢或者崩溃。

现在,较新出现的面向对象语言(比如Java)增强了内存管理机制,能够自动回收不被使用的内存,或者说能够回收垃圾内存,这种内存管理机制通常被称为“garbage collection(垃圾回收)”,简称GC。

Flex开发中所使用的ActionScript语言,简称AS,也是支持GC的一种语言,经过编译后的AS代码运行在AS虚拟机(简称AVM)中,由AVM自动完成垃圾内存回收的工作。

Flash Player 就是一个AVM,所以有时候我们将二者混为一谈。

既然AVM能够自动完成垃圾回收的功能,那么是不是Flex程序员就可以认为所开发的Flex应用不存内存泄露问题呢?答案是否定的。

在某些情况下,处理不妥当的代码仍然会导致内存泄露。

如何才能避免内存泄露?应该说,AS程序员在清楚了解Flash Palyer垃圾回收的基本原理,并且高度重视内存泄露这个问题才能有效避免内存泄露情况的发生。

Flash Player垃圾回收机制Flash Player垃圾回收工作是由垃圾回收器(garbage collector)完成的。

垃圾回收器是运行在后台的一个进程,它释放那些不再被应用所使用对象所占用的内存。

不再被应用所使用的对象是指那些不再会被那些活动着(工作着)的对象所“引用”的对象。

在AS中,对于非基本类型(Boolean, String, Number, uint, int)的对象,在对象之间传递的都是对象引用,而不是对象本身。

删除一个变量只是删除了对象的引用,而不是删除对象本身。

一个对象可以被多处引用,通过这些不同的引用所操作的都是同一个对象。

通过以下两段代码可以了解基本类型和非基本类型对象的差异:基本类型的值传递:private function testPrimitiveTypes():void{var s1:String="abcd"; //创建了一个新字符串s1,值为"abcd"var s2:String=s1; //String是基本类型,所以创建了一个新的字符串s2,s2的值拷贝自s1。

s2+="efg"; //改变s2的值s1不会受影响。

trace("s1:",s1); //输出abcdtrace("s2:",s2); //输出abcdefgvar n1:Number=100; //创建一个新的number,值为100。

var n2:Number=n1; //Number是基本类型,所以又创建一个新number n2,n2的值拷贝自n1。

n2=n2+100; //改变n2对n1不会有任何影响。

trace("n1",n1); //输出100trace("n2",n2); //输出200}非基本类型对象的引用传递:private function testNonPrimitiveType():void{// 创建一个新对象, 然后将其引用给变量a:var a:Object = {foo:"bar"}//将上面所创建对象的引用拷贝给变量b(通过变量b建立对对象的引用): var b:Object = a;//删除变量a中对对象的引用:delete(a);// 测试发现对象仍然存在并且被变量b所引用:trace(b.foo); // 输出"bar", 所以对象仍然存在}对于非基本类型对象,AS3采用两种方法来判定一个对象是否还有活动的引用,从而决定是否可以将其垃圾回收。

一种方法是引用计数法,一种方法是标记清除法。

Reference Counting引用计数法是判定对象是否有活动引用的最简单的一种方法,并且从AS1就开始在Flash中使用。

当创建一个对对象的引用后,对象的引用计数就加一,当删除一个引用时,对象的引用技术就减一。

如果对象的引用计数为0,那么它被标记为可被GC(垃圾回收器)删除。

例如:var a:Object = {foo:"bar"}// 现在对象的引用计数为1(a)var b:Object = a;// 现在对象的引用计数为2(a和b)delete(a);// 对象的引用计数又回到了1 (b)delete(b);// 对象的引用计数变成0,现在,这个对象可以被GC释放内存。

引用计数法很简单,并且不会增加CPU开销,可惜的是,当出现对象之间循环引用时它就不起作用了。

所谓循环引用就是指对象之间直接或者间接地彼此引用,尽管应用已经不再使用这些对象,但是它们的引用计数仍然大于0,因此,这些对象就不会被从内存中移除。

请看下面的范例:创建第一个对象:var a:Object = {};// 创建第二个对象来引用第一个对象:var b:Object = {foo:a};//使第一个对象也引用第二个对象:a.foo = b;// 删除两个活动引用:delete(a);delete(b);上面的例子中两个活动引用都已被删除,因此在应用程序中再也无法访问这两个对象。

但是它们的引用计数都是1,因为它们彼此相互引用。

这种对象间的相互引用可能会更加复杂(a引用b,b引用c,c又引用a,诸如此类),并且难以在代码中通过删除引用来使得引用技术为变为0。

Flash player 6 和7中就因为XML 对象中的循环引用而痛苦,每个XML节点既引用了该节点的子节点,又引用了该节点父节点。

因此,这些XML对象永远不会释放内存。

好在player 8增加了一种新的GC技术,叫做标记清除。

标记清除(Mark Sweeping)AS3使用的第二种查找不活动对象的GC策略就是标记清除。

Player从应用的根节点开始(在AS3中通常被称为”根(root)”),遍历所有其上的引用,标记每个它所发现的对象。

然后迭代遍历每个被标记的对象,标记它们的子对象。

这个过程第归进行,直到Player遍历了应用的整个对象树并标记了它所发现的每个东西。

在这个过程技术的时候,可以安全地认为,内存中那些没有被打标记的对象没有任何活动引用,因此可以被安全地释放内存。

可以通过下图可以很直观地了解这种机制(绿色的引用在标记清除过程中被遍历,绿色对象被打上了标记,白色对象将被释放内存)标记清除机制非常准确,但是这种方法需要遍历整个对象结构,因此会增大CPU 占用率。

因此,Flash Player9为了减少这种开销只是在需要的时候偶尔执行标记清除活动。

注意:上面所说的引用指的是“强引用(strong reference)”,flash player 在标记清除过程中会忽略“弱引用(weakness reference )”,也就是说,弱引用在标记清除过程中不被当做引用,不会阻止垃圾回收。

垃圾回收的时机Flash Player在运行时请求内存的速度受限于浏览器。

因此,Flash Player采用小量请求大块内存,而不是大量请求小块内存的内存请求策略。

同样,Flash Player在运行时释放内存速度也相对较慢,所以Flash Player会减少释放内存的次数,只有在必要的时候才释放内存。

也就是说,Flash Player的垃圾回收只有在必要的时候才会执行。

当前,Flash Player的垃圾回收发生在Flash Player需要另外请求内存之前。

这样,Flash Player可以重新利用垃圾对象所占用的内存资源,并且可以重新评估需要另外请求的内存数量,也会节省时间。

在程序的实际运行中验证了以上的说法,并不是每次应用申请内存时都会导致垃圾回收的执行,只有当Flash占用的内存紧张到一定程度时才会执行真正的垃圾回收,如果应用中内存开销增长是匀速的,那么计算机物理内存越大,则垃圾回收触发周期越长。

在我的测试环境中,计算机有2G的物理内存,直到打开FLSH 应用的浏览器占用700M物理内存之后才会导致Flash Player回收垃圾内存。

来自Adobe公司的Alex Harui 总结了两点:1.何时真正执行垃圾回收不可预知。

2.垃圾回收总是在请求内存的时候触发,而不是在对象删除时发生。

最后,有关FP9中垃圾回收一件非常重要的事情就是:垃圾回收不是立即进行的,而是延迟的。

当没有任何对象引用某个对象后,那个对象也不会立即被从内存中清除,相反,它们会在将来某个不确定的时候被移出(从开发者的角度来看)。

相关文档
最新文档