• <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)  編輯 收藏 引用 所屬分類: 框架/圖像/算法
            一本久久综合亚洲鲁鲁五月天| 色综合久久中文字幕无码| 一本一道久久精品综合| 精品久久久久久久久久久久久久久| 久久久久久国产精品免费免费| 精品伊人久久久| 国内精品伊人久久久久| 久久久久18| 久久久久无码精品国产| 久久人妻少妇嫩草AV无码蜜桃| 无码AV中文字幕久久专区| 国产精品久久久久久久久久免费| 久久久久av无码免费网| 2021久久精品国产99国产精品| 久久久久亚洲?V成人无码| 伊人色综合久久天天人手人婷| 国产成人精品久久亚洲| 无码精品久久久天天影视| 久久国产精品免费一区| 国产精品久久国产精麻豆99网站 | 久久亚洲高清观看| 久久亚洲精品成人无码网站| 久久精品无码一区二区三区免费 | 国产亚洲精久久久久久无码| 久久中文精品无码中文字幕| 国产一区二区三区久久精品| 三上悠亚久久精品| 久久人人爽人人爽人人片AV不| 久久精品国产第一区二区| 久久精品国产影库免费看| 亚洲狠狠婷婷综合久久久久| 久久亚洲sm情趣捆绑调教 | 久久九九有精品国产23百花影院| 伊人久久久AV老熟妇色| 久久亚洲熟女cc98cm| 久久这里有精品视频| 久久伊人五月天论坛| 久久久不卡国产精品一区二区| 国产农村妇女毛片精品久久| 久久精品国产99国产精偷 | 99久久成人国产精品免费|