• <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>

            兔子的技術(shù)博客

            兔子

               :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              202 Posts :: 0 Stories :: 43 Comments :: 0 Trackbacks

            留言簿(10)

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            最近使用Cocos2d-x開發(fā)游戲,發(fā)現(xiàn)Cocos2d-x的內(nèi)存管理采用Objective-C的機(jī)制,大喜過望。因?yàn)橹灰獔?jiān)持Objective-C的原則“誰創(chuàng)建誰釋放,誰備份誰釋放”的原則即可確保內(nèi)存使用不易出現(xiàn)Bug。
            但是因?yàn)楸旧黹_放的游戲需要使用到多線程技術(shù),導(dǎo)致測(cè)試的時(shí)候總是莫名其妙的導(dǎo)致空指針錯(cuò)誤。而且是隨機(jī)出現(xiàn),糾結(jié)了2天無果后,開始懷疑Cocos2d-X的內(nèi)存本身管理可能存在問題。懷著這樣的想法,
            一步一步的調(diào)試,發(fā)現(xiàn)經(jīng)常出現(xiàn)指針異常的變量總是在調(diào)用autorelease后一會(huì)就莫名其妙再使用的時(shí)候就拋異常。狠下心,在它的析構(gòu)函數(shù)里面斷點(diǎn)+Log輸出信息。發(fā)現(xiàn)對(duì)象被釋放了。一時(shí)也很迷糊,因?yàn)閷?duì)象只是
            autorelease,并沒有真正釋放,是誰導(dǎo)致它釋放的?

            然后就去看了CCAutoreleasePool的源碼,發(fā)現(xiàn)存在Cocos2d-X的內(nèi)存管理在多線程的情況下存在如下問題



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


            解決辦法:在PoolManager給每個(gè)線程根據(jù)pthread_t的線程id生成一個(gè)CCArray的stack的嵌套管理自動(dòng)釋放池。源碼如下
            所以我在Push的時(shí)候根據(jù)當(dāng)前線程的pthread_t的線程id生成一個(gè)CCArray的stack來存儲(chǔ)該線程對(duì)應(yīng)的Autoreleasepool的嵌套對(duì)象
            源碼如下

               

            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//////







            轉(zhuǎn)自:http://www.ityran.com/thread-3364-1-1.html
            posted on 2012-10-15 18:01 會(huì)飛的兔子 閱讀(4208) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 框架/圖像/算法
            精品国产一区二区三区久久蜜臀| 91精品国产高清久久久久久国产嫩草| 97久久婷婷五月综合色d啪蜜芽 | 亚洲国产另类久久久精品 | 国产精品久久久久久久久久免费| 久久精品国产第一区二区| 狠狠色婷婷久久综合频道日韩 | 国产成年无码久久久久毛片| 久久精品国产精品亚洲人人| 亚洲愉拍99热成人精品热久久| 国产成人精品久久亚洲高清不卡 | 狠狠综合久久AV一区二区三区| 色综合久久久久网| 久久亚洲日韩精品一区二区三区| 久久99精品久久久久久秒播| 久久国产亚洲高清观看| 中文字幕无码久久久| 狠狠色丁香婷婷综合久久来来去| 精品国产一区二区三区久久久狼| 理论片午午伦夜理片久久| 久久精品国产秦先生| WWW婷婷AV久久久影片| 久久99精品久久久大学生| 亚洲欧美国产日韩综合久久| 日韩一区二区久久久久久| 国产成人久久精品激情| 久久久久成人精品无码中文字幕| 久久久久青草线蕉综合超碰| 亚洲国产精品嫩草影院久久 | 亚洲国产精品无码久久一区二区| 少妇被又大又粗又爽毛片久久黑人 | 久久精品无码一区二区三区免费| 色综合久久中文色婷婷| 国产精品久久久天天影视| 久久亚洲AV成人出白浆无码国产| 99久久国产综合精品女同图片| 久久久久亚洲AV无码观看 | 国产91色综合久久免费| 99久久久精品免费观看国产| 久久av无码专区亚洲av桃花岛| 久久精品午夜一区二区福利|