作者相關(guān),轉(zhuǎn)載請(qǐng)保留: http://as3blog.com/as3/as3tip-take-care-of-resource
摒棄了attachMovie 之后的AS3,采用了類似DOM 的操作方式。addChild、removeChild 、getChildAt 等方法開始成為AS3中顯示(在屏幕上渲染)、操作圖形的主要方法。由于AS1、AS2完全是依賴于attchMovie 的思想,因此對(duì)于傳統(tǒng)Flash開發(fā)人員來說,轉(zhuǎn)變到新的addChild 的確需要下一番功夫。
由于新的“DisplayObject”在內(nèi)存的使用上非!懊舾小薄M捎诓涣嫉木幊塘(xí)慣會(huì)造成不必要的內(nèi)存泄漏,因此,我們不得不比AS1、 AS2時(shí)代更加深入到內(nèi)存管理了。我想,每一個(gè)Flash開發(fā)人員,包括我自己,都應(yīng)該花一番功夫仔細(xì)體會(huì)“內(nèi)存管理”這幾個(gè)字的含義。畢竟我們學(xué)習(xí) AS3是為了開發(fā)比AS1、2時(shí)代更加先進(jìn)、高效而且內(nèi)存占用小的應(yīng)用程序,如果還是開發(fā)一些簡(jiǎn)單的應(yīng)用,也就失去我們每一個(gè)人使用AS3的意義了。
我覺得,由于GC是Flash 應(yīng)用程序內(nèi)存管理的核心,我應(yīng)該先從AS3中的Garbage Collector(簡(jiǎn)稱GC)開始說起。AS3的GC功能比AS1、2中的要強(qiáng)大的多。然而,強(qiáng)大的同時(shí),也帶來了一定程度的復(fù)雜性。但是也不至于非常復(fù)雜,我覺得比C++等傳統(tǒng)語言要容易掌握得多。
在研究?jī)?nèi)存如何回收之前,先說一下變量的創(chuàng)建:
在Flash中,我們每建立一個(gè)非原生變量時(shí)(Boolean, String, Number, uint, int 這些是原生變量),這個(gè)變量名只是一個(gè)reference(指向,有時(shí)候也成為“引用”)而已,而并非這個(gè)變量本身。例如: var a:int = 5; //a就是5 var b:int = a; //b是a,也就是5 a = 4; trace(b); // 是5,而不是4! //改變b的值,a不發(fā)生變化。反之亦然 var c:Object = {name:”aw”, blog:”www.awflasher.com/blog”}; //c只是指向一個(gè)內(nèi)部的Object,為了描述方便,稱其為“O” var d:Object = c; //d指向c,指向了同一個(gè)Object“O” c.name = “bw” trace(d.name); //不是aw,而是bw了 //改變c也好,改變d也罷,其實(shí)是改變了那個(gè)“O”,因此改變c的時(shí)候,d的值也就變了。因此d.name已經(jīng)被改變?yōu)榱恕癰w”。
首先,明確一點(diǎn),GC會(huì)按照一定的時(shí)間周期進(jìn)行內(nèi)存清理(memory sweep)。因此不要因?yàn)閐elete掉一個(gè)object后檢查System.totalMemory 內(nèi)存就沒有反應(yīng)而懷疑GC是否正常。那么GC為什么要按照一定的時(shí)間周期進(jìn)行清理呢。這還要得從GC的具體工作原理說起。
GC的兩個(gè)回收體系: 1、“Reference Counting” - 引用計(jì)數(shù)器 這個(gè)體系是自從AS1時(shí)代就有的體系,它的工作原理非常簡(jiǎn)單:系統(tǒng)計(jì)算每一個(gè)對(duì)象被指向,或者說引用的次數(shù)。比如 var a:Object = {name:”aw”, blog:”www.awflasher.com/blog”};
這時(shí)候,這個(gè)Object(我們?nèi)匀环Q為“O”),有一次引用,它的引用計(jì)數(shù)器為1(來自a)。我們?cè)俳⒁粋(gè)對(duì)象b,并指向到a: var b:Object = a;
這時(shí)候“O”引用計(jì)數(shù)器變?yōu)榱?(來自a、b)。 我們刪除一個(gè),比如先刪除b: delete b; 這時(shí)候引用計(jì)數(shù)器為(2-1=1)1,GC不操作 再刪除另外一個(gè)a: delete a;“O”引用計(jì)數(shù)器變?yōu)椋?-1=0)0,GC出面干掉這個(gè)對(duì)象。 這套體系很輕便,CPU壓力較小。但是它也有缺陷。當(dāng)我們的對(duì)象內(nèi)部互相引用的時(shí)候,麻煩就來了。例如: var a:Object = {name:”aw”, description:”unknown”};
// 建立一個(gè)對(duì)象a,仍然假設(shè)內(nèi)部對(duì)象為“O”,這時(shí)O的引用次數(shù)為1 var b:Object = {nameObj:a, url:”awflasher.com”}; // b引用了a,同時(shí)創(chuàng)建了新的內(nèi)部對(duì)象“P”。這時(shí)O的引用次數(shù)為2,P為1 a.myDescription = b; // a的myDescription屬性指向到了b。這樣,P的引用次數(shù)也為2了。 // 是不是有點(diǎn)頭暈?靜下來,畫個(gè)圖慢慢看看:) delete a; delete b; 兩次delete操作后,O、P的引用次數(shù)都是1,它們將繼續(xù)占用你的內(nèi)存!癛eference Counting” 體系無能為力了。
2、“Mark Sweeping” - 標(biāo)記清除法則
GC的第一種機(jī)制“Reference Counting”,在FlashPlayer8之前是GC唯一的機(jī)制。FlashPlayer6和7由于引入了復(fù)雜的OOP開發(fā)模式,尤其是7引入了類似Java、C++等強(qiáng)大OOP語言的語法。利用Flash設(shè)計(jì)的復(fù)雜項(xiàng)目越來越多。由于Flash開發(fā)人員大多不了解GC,而Java、C++的開發(fā)人員又已經(jīng)習(xí)慣了強(qiáng)大的GC(無論是自動(dòng)的還是手動(dòng)的)。因此FlashPlayer6、7的內(nèi)存問題開始浮現(xiàn)出來。
Okay,F(xiàn)lash Player8引入了新的“Mark Sweeping”機(jī)制。我想這也是當(dāng)年Macromedia(Adobe)基于退出Player8的原因吧。ㄟ記得當(dāng)年Flash8的介紹視頻么,效率提高是一個(gè)革命性的改進(jìn))
下面就來講述“Mark Sweeping” - 標(biāo)記清除法則的工作原理。 FlashPlayer會(huì)從root開始,遍歷系統(tǒng)的每一個(gè)變量,并對(duì)有指向的對(duì)象之間,記錄一次聯(lián)系。在遍歷結(jié)束之后,凡是與root不相聯(lián)系的對(duì)象,被FlashPlayer無情地干掉。
Okay,回到剛才的例子,當(dāng)我們delete a,并delete b之后,root與O、P就劃清了界線。這時(shí)候,GC就可以進(jìn)行一次肅清了。然而,由于這種“Mark Sweeping”要遍歷所有的對(duì)象,因此非常消耗資源。這也就回到了當(dāng)初的問題:“GC為什么要按照一定的時(shí)間周期進(jìn)行清理“ - 因?yàn)椴荒芙oCPU造成太大的負(fù)擔(dān)。
我個(gè)人猜測(cè),GC的內(nèi)部清除策略應(yīng)該是在某一次事件(例如delete)發(fā)生后,在CPU比較空閑、RAM分配相對(duì)合理的情況下執(zhí)行的。
Okay,不要以為有了“Mark Sweeping”就萬事大吉了。由于GC不會(huì)即時(shí)進(jìn)行,因此你的對(duì)象會(huì)在一段時(shí)間內(nèi)“陰魂不散”!對(duì)于一個(gè)追求完美的開發(fā)人員來說,這意味著它們內(nèi)部的某些機(jī)制會(huì)在被刪除之后繼續(xù)工作:AS語句會(huì)繼續(xù)執(zhí)行、聲音會(huì)繼續(xù)播放、事件會(huì)繼續(xù)觸發(fā)!
KirupaForum有網(wǎng)友說,“All you got to do is pray the garbage collector doesn’t break down.”,確實(shí),如果一個(gè)應(yīng)用程序要運(yùn)行上一個(gè)多小時(shí),那么慢慢流逝的內(nèi)存會(huì)讓你的用戶對(duì)你的產(chǎn)品失望(例如游戲)。因此我們需要有一個(gè)良好的資源管理策略。
待續(xù)……
經(jīng)典論壇討論: http://bbs.blueidea.com/thread-2745066-1-1.html
本文鏈接:http://www.95time.cn/tech/multimedia/2007/4705.asp
出處:藍(lán)色理想
責(zé)任編輯:elesa
◎進(jìn)入論壇Flash專欄版塊參加討論
|