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

            最新評論

            閱讀排行榜

            評論排行榜

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

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



            如圖: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的時候會發(fā)生是么事情呢?
            答案很簡單,就是obj在time 3的時候就被釋放了,而我們期望它在time 4的時候才釋放。所以就導致我上面說的,在多線程下面,cocos2d-x的autorelease變量會發(fā)生莫名其妙的指針異常。


            解決辦法:在PoolManager給每個線程根據(jù)pthread_t的線程id生成一個CCArray的stack的嵌套管理自動釋放池。源碼如下
            所以我在Push的時候根據(jù)當前線程的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//////







            轉(zhuǎn)自:http://www.ityran.com/thread-3364-1-1.html
            posted on 2012-10-15 18:01 會飛的兔子 閱讀(4213) 評論(0)  編輯 收藏 引用 所屬分類: 框架/圖像/算法
            香蕉99久久国产综合精品宅男自 | 伊人久久大香线蕉精品不卡| 久久精品国产精品亚洲下载| 久久无码精品一区二区三区| 亚洲乱码精品久久久久..| 中文字幕日本人妻久久久免费| 婷婷久久久亚洲欧洲日产国码AV | 狼狼综合久久久久综合网| 久久精品9988| 欧美伊人久久大香线蕉综合 | 久久乐国产精品亚洲综合 | 99久久久久| 久久久久亚洲AV成人片| 综合久久给合久久狠狠狠97色 | 国产一级做a爰片久久毛片| 女同久久| 久久se精品一区精品二区国产| 亚洲精品无码久久千人斩| 国产高潮久久免费观看| 狠狠色丁香久久婷婷综| 欧美精品一区二区久久| 久久本道伊人久久| 久久久亚洲欧洲日产国码二区| 无码人妻少妇久久中文字幕 | 国产精品久久久久jk制服| 婷婷久久久亚洲欧洲日产国码AV| 国产—久久香蕉国产线看观看| 久久棈精品久久久久久噜噜| 亚洲伊人久久综合中文成人网| 国产精品日韩欧美久久综合| 久久久久成人精品无码中文字幕| 久久妇女高潮几次MBA| 老色鬼久久亚洲AV综合| 亚洲综合伊人久久大杳蕉| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 一本色道久久综合狠狠躁篇| 国产农村妇女毛片精品久久| 亚洲国产精品久久| 93精91精品国产综合久久香蕉| 亚洲国产精品久久| 欧美日韩成人精品久久久免费看|