cocos2dx 記憶體管理機制(2)

2022-09-04 08:39:13 字數 2958 閱讀 2902

首先我們要知道,cocos2d-x的引擎執行緒是單執行緒的,它不停的呼叫乙個主迴圈來繪製當前的scene ,同時對一些自動釋放的物件進行管理。

一、現在開始定位,我們知道win32 下cocos2dx程式入口

run方法裡面有這麼一句

ccdirector::shareddirector()->mainloop();
進入mainloop方法檢視

void ccdisplaylinkdirector::mainloop(void)

else if (! m_binvalid)

}

在這個主迴圈中 

drawscene

(); 渲染場景,同時ccpoolmanager

::sharedpoolmanager()->pop(); 釋放自動釋放池中的物件。

二、在對pop釋放物件分析的之前,首先有必要了解

為什麼需要自動釋放池這個東西

下面這段解釋摘抄自:

我們知道

cocos2d-x 使用了自動釋放池,自動管理物件,知其然!其所以然呢?為什麼需要自動釋放池,它在整個框架之中又起著什麼樣的作用!在了解這一點之前,我們需要 知道

ccobject 從建立之初,到最終銷毀,經歷了哪些過程。在此,一葉總結以下幾點(重點理解):

上面是乙個物件的大致流程,我們將物件分為兩個時期,乙個是剛建立時期

,自引用為 1(如果為

0 就會釋放物件,這是基本原則,所以要大於 0) 的時期,另乙個是使用時期

。上面說到,為了保證建立時期的物件不被銷毀,所以自引用(並沒有實際的使用)初始化為

1,這就意味著我們需要乙個合適的時機,來解除這樣的自引用。

何時?在幀過度之時!(這樣可保證當前幀能正確使用物件而沒有被銷毀。)怎麼樣釋放?由於是自引用,我們並不能通過其它方式訪問到它,所以就有了自動釋放池,我們變相的將「自引用」轉化「自動釋放池引用」,來標記乙個

「建立時期的物件」

。然後在幀過度之時,通過自動釋放池管理,統一釋放 「釋放池引用」,也就意味著,去除了「自身引用」。幀過度之後的物件,才是真正的被使用者所管理。

總結:通過對上面這段話的理解我們就可以知道了:

三、自動釋放池解除引用的過程(pop)

首先,我們進入pop()這個方法中:

void ccpoolmanager::pop()

int ncount = m_preleasepoolstack->count();

m_pcurreleasepool->clear();

if(ncount > 1)

m_pcurreleasepool = (ccautoreleasepool*)m_preleasepoolstack->objectatindex(ncount - 2);

}/*m_pcurreleasepool = null;*/

}

在這個方法中我們可以知道,其釋放過程是這樣的:

在前面一篇文章中 cocos2d-x

記憶體管理機制(1) 我們已經知道 

ccpoolmanager 物件自動釋放管理類中儲存著乙個當前的物件自動釋放池和乙個物件釋放池陣列。

在pop方法中,首先是對當前的物件自動釋放池進行clear操作,顯然就是對當前釋放池中的所有物件進行解除引用的操作。下面進入這個clear方法:

void ccautoreleasepool::clear()

m_pmanagedobjectarray->removeallobjects();}}

我們在for迴圈中可以看到 --(pobj->m_uautoreleasecount); 這個是對引用物件解除自動物件管理,自動管理值減一。

物件新增到自動釋放池的時候 m_uautoreleasecount = 1,表示給自動釋放池自動管理;那麼現在減1之後,m_uautoreleasecount = 0,表示不是給自動釋放池管理了。

而且我們還可以注意到 ccarray_foreach_reverse 其解除引用是逆序的,由此我們也可以猜測到 :自動釋放池採用的是乙個棧結構(filo)。

--m_uautoreleasecount 之後。就是  m_pmanagedobjectarray

->

removeallobjects

(); 將自動釋放池中的所有物件進行remove,那麼我們跟蹤這個remove的過程會發現,其實最終也是對物件進行release操作,因為物件autorelease之後,

m_ureference 的值為1,那麼這裡release之後,就變成0了,那麼就會自動釋放這個物件。

所以經過這個clear之後,當前自動管理物件池中的所有物件都被解除了自身引用。

接著我們再回到pop方法中,

if(ncount > 1)

m_pcurreleasepool = (ccautoreleasepool*)m_preleasepoolstack->objectatindex(ncount - 2);

}

我們將當前的物件自動釋放池clear之後,需要從自動釋放池陣列中刪除該物件自動管理池;然後將陣列中的倒數第二個自動釋放池作為當前自動釋放池。

從這裡,我們也可以大致理解到,自動釋放池陣列,其實本質上也是乙個棧結構了吧,只不過是通過陣列來實現的。

自動釋放池解除引用的過程大致就是這樣子了!

四、總結

這兩篇文章大致講述了cocos2dx中的記憶體管理,其實總結來說的話就兩個方面的內容:

①把物件新增到自動釋放池進行自動管理(建立時期);

②自動釋放池解除對物件的自動管理,交由使用該物件的物件進行管理(使用時期)。

把握理解其中的過程就應該沒有什麼問題的!

cocos2d x記憶體管理機制

c 記憶體機制,採用new關鍵字例項化的物件,必須在不使用的時候手動delete掉,否則new的時候開闢的記憶體就不能被 造成記憶體洩露 npc n1 new npc if exit 0 cocos2d x 記憶體管理的方式,cocos2d x採用引用計數的方式進行記憶體管理,當乙個物件的引用計數為...

Cocos2dx 記憶體管理機制(1)

1.引用計數機制 要了解cocos2dx引用計數的機制,首先我們來看看ccobject這個類 class cc dll ccobject public cccopying friend class ccautoreleasepool 說明 當m ureference 0時會自動釋放該物件,每引用一次...

cocos2dx 學習( )記憶體管理機制

一 題記 關於cocos2dx 的記憶體管理機制,想必大家都能清楚說出是通過引用計數 reference count 和自動釋放池 autoreleasepool 但是不知大家是否知道其中具體的執行的細節呢?反正在寫這篇blog之前我是一知半解的,而且在粗略的看了下 poolmanager 的原始碼...