cocos2d-js 瀏覽器與JSB內存管理機制的不一樣

寫這邊文章的主要目的是爲了理解使用cocos3d-js開發app時,瀏覽器調試與真機狀況不一致的緣由程序員

1、瀏覽器中內存管理機制算法

  HTML5版本運行時,整個遊戲只存在JS腳本與一些必要的資源文件,這時候內存管理是由JS內存管理機制來控制的。瀏覽器

  JS內存管理有一套很是智能的機制,稱爲垃圾回收器。垃圾回收器有兩種策略--引用計數與標記清除,判斷某個對象是否可回收,app

而後週期性啓動回收線程把以前已標記爲可回收的對象銷燬回收。this

  引用計數:引用計數使用系統記錄一個對象被引用的次數,當對象被引用的次數變爲0時,該對象即被視做垃圾而被回收;spa

這是一種比較簡單高效的策略,可是引用計數對循環引用的狀況難以處理;這時候就引入了另外一種策略:標記清除線程

  標記清除:這樣的方法是產生跟蹤對象的關係圖,而後進行垃圾回收。其算法是首先將程序中正在使用的對象視爲「根對象」,3d

從根對象開始查找它們所引用的堆空間,並在這些堆空間上作標記,可是這種方法每每會產生比較大的計算開銷;指針

  不斷怎麼說,JS的內存管理足夠智能,使得程序員能夠沒必要關注內存管理,反而要關注如何讓JS的內存管理機制可以搞高效的調試

運轉。

2、JSB

  cocos2d-js在發佈爲app時,使用的是JSB,而JSB底層使用的是cocos2d-x,當代碼運行時,就存在了兩套運行環境--JS運行環境和Cocos2d-x

的鏡像運行環境。項目的代碼在JS運行環境中每添加一個節點,cocos2d-x中就會相應的添加一個相同的節點,可是這兩個運行環境是不徹底

相同的,好比說內存管理機制:JS使用JS本身的垃圾回收機制,而cocos2d-x使用的是cocos2d-x本身的一套內存管理機制--智能指針的變種:

計數器機制(不是上方的引用計數)

  cocos2d-x爲幾乎全部的類添加了一個基類Ref類,這個類只有一個做用:管理cocos對象的計數,retain()計數加一,release()計數減一

若計數爲零,則自動釋放該對象(緣由以後解釋)

  而支持cocos2d-x自動內存管理的類(Node、Action等)都存在一個方法Create(),這個Create中有兩個要關注的點:new與autorelease();

在使用create時,會使用new一個對象,而且計數設爲1(retain()),而後會調用autorelease(顧名思義會自動釋放該對象,計數減一);

  如今來看看autorelease,它會將對象放入AutoreleasePool池中,有一個AutoreleaseManger來管理AutoreleasePool,在每一幀結束的

時候,AutoreleasePool中的對象會調用release,若計數爲0,則會內釋放,這樣就實現了cocos2d-x的內存自動回收機制。

3、形成錯誤的緣由

  舉個栗子:

let ball = new cc.Sprite(""); this.scheduleOnce(function(){ this.addChind(ball); }.bind(this),2);

這段代碼在瀏覽器上時沒有問題的,可是打包到手機上,就會出錯。緣由很簡單,new以後並無立刻addChind,這時候計數爲一,一幀以後被清除,2s以後再去添加

就會找不到該對象。

這時候能夠改爲下面的代碼

let ball = new cc.Sprite(""); ball.retain(); //計數加一
this.scheduleOnce(function(){ this.addChind(ball); ball.release() //計數減一
}.bind(this),2);
相關文章
相關標籤/搜索