• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            兔子的技術博客

            兔子

               :: 首頁 :: 聯系 :: 聚合  :: 管理
              202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

            留言簿(10)

            最新評論

            閱讀排行榜

            評論排行榜

            最近使用Cocos2d-x開發游戲,發現Cocos2d-x的內存管理采用Objective-C的機制,大喜過望。因為只要堅持Objective-C的原則“誰創建誰釋放,誰備份誰釋放”的原則即可確保內存使用不易出現Bug。
            但是因為本身開放的游戲需要使用到多線程技術,導致測試的時候總是莫名其妙的導致空指針錯誤。而且是隨機出現,糾結了2天無果后,開始懷疑Cocos2d-X的內存本身管理可能存在問題。懷著這樣的想法,
            一步一步的調試,發現經常出現指針異常的變量總是在調用autorelease后一會就莫名其妙再使用的時候就拋異常。狠下心,在它的析構函數里面斷點+Log輸出信息。發現對象被釋放了。一時也很迷糊,因為對象只是
            autorelease,并沒有真正釋放,是誰導致它釋放的?

            然后就去看了CCAutoreleasePool的源碼,發現存在Cocos2d-X的內存管理在多線程的情況下存在如下問題



            如圖:thread 1和thread 2是獨立的兩個線程,它們之間存在CPU分配的交叉集,我們在time 1的時候push一個autorelease的自動釋放池,在該線程的末尾,即time 3的時候pop它。同理在thread 2的線程里面,在time 2的時候push一個自動釋放池,在time 4的時候釋放它,即Pop.
            此時我們假設在thread 2分配得到CPU的時候有一個對象obj自動釋放,即obj-autorelease().那么在time 3的時候會發生是么事情呢?
            答案很簡單,就是obj在time 3的時候就被釋放了,而我們期望它在time 4的時候才釋放。所以就導致我上面說的,在多線程下面,cocos2d-x的autorelease變量會發生莫名其妙的指針異常。


            解決辦法:在PoolManager給每個線程根據pthread_t的線程id生成一個CCArray的stack的嵌套管理自動釋放池。源碼如下
            所以我在Push的時候根據當前線程的pthread_t的線程id生成一個CCArray的stack來存儲該線程對應的Autoreleasepool的嵌套對象
            源碼如下

               

            1

            2

            3

            4

            5

            6

            7

            8

            9

            10

            11

            12

            13

            14

            15

            16

            17

            18

            19

            20

            21

            22

            23

            24

            25

            26

            27

            28

            29

            30

            31

            32

            33

            34

            35

            36

            37

            38

            39

            40

            41

            42

            43

            44

            45

            46

            47

            48

            49

            50

            51

            52

            53

            54

            55

            56

            57

            58

            59

            60

            61

            62

            63

            64

            65

            66

            67

            68

            69

            70

            71

            72

            73

            74

            75

            76

            77

            78

            79

            80

            81

            82

            83

            84

            85

            86

            87

            88

            89

            90

            91

            92

            93

            94

            95

            96

            97

            98

            99

            100

            101

            102

            103

            104

            105

            106

            107

            108

            109

            110

            111

            112

            113

            114

            115

            116

            117

            118

            119

            120

            121

            122

            123

            124

            125

            126

            127

            128

            129

            130

            131

            132

            133

            134

            135

            136

            137

            138

            139

            140

            141

            142

            143

            144

            145

            146

            147

            148

            149

            150

            151

            152

            153

            154

            155

            156

            157

            158

            159

            160

            161

            162

            163

            164

            165

            166

            167

            168

            169

            170

            171

            172

            173

            174

            175

            176

            177

            178

            179

            180

            181

            182

            183

            184

            185

            186

            187

            188

            189

            190

            191

            192

            193

            194

            195

            196

            197

            198

            199

            200

            201

            202

            203

            204

            205

            206

            207

            208

            209

            210

            //--------------------------------------------------------------------

            //

            // CCPoolManager

            //

            //--------------------------------------------------------------------


            /////【diff - begin】- by layne//////


            CCPoolManager* CCPoolManager::sharedPoolManager()

            {

                if (s_pPoolManager == NULL)

                {

                    s_pPoolManager = new CCPoolManager();

                }

                return s_pPoolManager;

            }


            void CCPoolManager::purgePoolManager()

            {

                CC_SAFE_DELETE(s_pPoolManager);

            }


            CCPoolManager::CCPoolManager()

            {

                //    m_pReleasePoolStack = new CCArray();   

                //    m_pReleasePoolStack->init();

                //    m_pCurReleasePool = 0;


                m_pReleasePoolMultiStack = new CCDictionary();

            }


            CCPoolManager::~CCPoolManager()

            {


                //    finalize();


                //    // we only release the last autorelease pool here

                //    m_pCurReleasePool = 0;

                //    m_pReleasePoolStack->removeObjectAtIndex(0);

                //   

                //    CC_SAFE_DELETE(m_pReleasePoolStack);


                finalize();


                CC_SAFE_DELETE(m_pReleasePoolMultiStack);

            }


            void CCPoolManager::finalize()

            {

                if(m_pReleasePoolMultiStack->count() > 0)

                {

                    //CCAutoreleasePool* pReleasePool;

                    CCObject* pkey = NULL;

                    CCARRAY_FOREACH(m_pReleasePoolMultiStack->allKeys(), pkey)

                    {

                        if(!pkey)

                            break;

                        CCInteger *key = (CCInteger*)pkey;

                        CCArray *poolStack = (CCArray *)m_pReleasePoolMultiStack->objectForKey(key->getValue());

                        CCObject* pObj = NULL;

                        CCARRAY_FOREACH(poolStack, pObj)

                        {

                            if(!pObj)

                                break;

                            CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj;

                            pPool->clear();

                        }

                    }

                }

            }


            void CCPoolManager::push()

            {

                //    CCAutoreleasePool* pPool = new CCAutoreleasePool();       //ref = 1

                //    m_pCurReleasePool = pPool;

                //   

                //    m_pReleasePoolStack->addObject(pPool);                   //ref = 2

                //   

                //    pPool->release();                                       //ref = 1


                pthread_mutex_lock(&m_mutex);


                CCArray* pCurReleasePoolStack = getCurReleasePoolStack();

                CCAutoreleasePool* pPool = new CCAutoreleasePool();         //ref = 1

                pCurReleasePoolStack->addObject(pPool);                               //ref = 2

                pPool->release();                                           //ref = 1   


                pthread_mutex_unlock(&m_mutex);

            }


            void CCPoolManager::pop()

            {

                //    if (! m_pCurReleasePool)

                //    {

                //        return;

                //    }

                //   

                //    int nCount = m_pReleasePoolStack->count();

                //   

                //    m_pCurReleasePool->clear();

                //   

                //    if(nCount > 1)

                //    {

                //        m_pReleasePoolStack->removeObjectAtIndex(nCount-1);

                //        

                //        //         if(nCount > 1)

                //        //         {

                //        //             m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);

                //        //             return;

                //        //         }

                //        m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);

                //    }

                //   

                //    /*m_pCurReleasePool = NULL;*/


                pthread_mutex_lock(&m_mutex);   


                CCArray* pCurReleasePoolStack = getCurReleasePoolStack();

                CCAutoreleasePool* pCurReleasePool = getCurReleasePool();   

                if (pCurReleasePoolStack && pCurReleasePool)

                {

                    int nCount = pCurReleasePoolStack->count();


                    pCurReleasePool->clear();


                    if(nCount > 1)

                    {

                        pCurReleasePoolStack->removeObject(pCurReleasePool);

                    }

                }


                pthread_mutex_unlock(&m_mutex);

            }


            void CCPoolManager::removeObject(CCObject* pObject)

            {

                //    CCAssert(m_pCurReleasePool, "current auto release pool should not be null");

                //   

                //    m_pCurReleasePool->removeObject(pObject);


                pthread_mutex_lock(&m_mutex);

                CCAutoreleasePool* pCurReleasePool = getCurReleasePool();

                CCAssert(pCurReleasePool, "current auto release pool should not be null");


                pCurReleasePool->removeObject(pObject);

                pthread_mutex_unlock(&m_mutex);   

            }


            void CCPoolManager::addObject(CCObject* pObject)

            {

                //    getCurReleasePool()->addObject(pObject);


                pthread_mutex_lock(&m_mutex);   

                CCAutoreleasePool* pCurReleasePool = getCurReleasePool(true);

                CCAssert(pCurReleasePool, "current auto release pool should not be null");


                pCurReleasePool->addObject(pObject);

                pthread_mutex_unlock(&m_mutex);     

            }


            CCArray* CCPoolManager::getCurReleasePoolStack()

            {

                CCArray* pPoolStack = NULL;

                pthread_t tid = pthread_self();

                if(m_pReleasePoolMultiStack->count() > 0)

                {

                    pPoolStack = (CCArray*)m_pReleasePoolMultiStack->objectForKey((int)tid);

                }


                if (!pPoolStack) {

                    pPoolStack = new CCArray();

                    m_pReleasePoolMultiStack->setObject(pPoolStack, (int)tid);

                    pPoolStack->release();

                }


                return pPoolStack;

            }


            CCAutoreleasePool* CCPoolManager::getCurReleasePool(bool autoCreate)

            {

                //    if(!m_pCurReleasePool)

                //    {

                //        push();

                //    }

                //   

                //    CCAssert(m_pCurReleasePool, "current auto release pool should not be null");

                //   

                //    return m_pCurReleasePool;


                CCAutoreleasePool* pReleasePool = NULL;



                CCArray* pPoolStack = getCurReleasePoolStack();

                if(pPoolStack->count() > 0)

                {

                    pReleasePool = (CCAutoreleasePool*)pPoolStack->lastObject();

                }


                if (!pReleasePool && autoCreate) {

                    CCAutoreleasePool* pPool = new CCAutoreleasePool();         //ref = 1

                    pPoolStack->addObject(pPool);                               //ref = 2

                    pPool->release();                                           //ref = 1


                    pReleasePool = pPool;

                }


                return pReleasePool;

            }


            /////【diff - end】- by layne//////







            轉自:http://www.ityran.com/thread-3364-1-1.html
            posted on 2012-10-15 18:01 會飛的兔子 閱讀(4220) 評論(0)  編輯 收藏 引用 所屬分類: 框架/圖像/算法
            伊人久久大香线蕉综合Av| 777午夜精品久久av蜜臀| 久久综合国产乱子伦精品免费| 国产精品99久久精品爆乳| 66精品综合久久久久久久| 日韩亚洲欧美久久久www综合网| 久久久青草青青亚洲国产免观| 久久综合噜噜激激的五月天| 日韩AV无码久久一区二区| 久久精品aⅴ无码中文字字幕不卡| 国产亚洲综合久久系列| 国产精品成人无码久久久久久| 国产成人精品久久一区二区三区av| 国内精品久久久久久不卡影院| 久久天天躁狠狠躁夜夜2020| 2020国产成人久久精品| 性欧美丰满熟妇XXXX性久久久| 久久亚洲精品中文字幕| 国产精品99久久久久久人| 999久久久免费国产精品播放| 久久99精品久久久久久不卡| 午夜福利91久久福利| 亚洲熟妇无码另类久久久| 成人综合伊人五月婷久久| 狠狠久久综合| 伊人色综合久久天天人手人婷 | 久久亚洲国产成人精品无码区| 久久久久亚洲AV成人网人人网站| 久久久久亚洲AV无码专区首JN| 久久99热只有频精品8| 久久婷婷色综合一区二区| 欧洲精品久久久av无码电影| 久久人妻少妇嫩草AV无码蜜桃| 无码久久精品国产亚洲Av影片| 国产精品综合久久第一页| 无码精品久久久天天影视| 欧洲成人午夜精品无码区久久| 久久国产精品一国产精品金尊| 久久久久九九精品影院| 国产精品美女久久久| 久久人做人爽一区二区三区|