• <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)  編輯 收藏 引用 所屬分類: 框架/圖像/算法
            国产精品一区二区久久精品涩爱 | 99久久99这里只有免费费精品| 久久人妻AV中文字幕| 精品久久久无码人妻中文字幕豆芽| 国产午夜久久影院| 亚洲日韩欧美一区久久久久我| 97精品国产97久久久久久免费 | 久久久艹| 2021精品国产综合久久| 亚洲美日韩Av中文字幕无码久久久妻妇| 久久天天躁夜夜躁狠狠| 91精品日韩人妻无码久久不卡 | 久久精品18| 精品少妇人妻av无码久久| 一本久久精品一区二区| 免费观看成人久久网免费观看| 久久综合亚洲色一区二区三区| 2020最新久久久视精品爱| 热re99久久6国产精品免费| 久久亚洲色一区二区三区| 99久久成人18免费网站| 97久久久精品综合88久久| 伊人久久大香线蕉av不卡| 亚洲午夜精品久久久久久app| 91精品国产91热久久久久福利| 欧美va久久久噜噜噜久久| 大香伊人久久精品一区二区| 久久久久久国产精品美女| 狠狠久久综合伊人不卡| 99久久精品免费看国产| 精品多毛少妇人妻AV免费久久| 亚洲国产精品久久久久婷婷老年| 国产成人久久激情91| 国产精品一久久香蕉国产线看| 久久亚洲精品成人AV| 久久亚洲中文字幕精品有坂深雪| 久久夜色精品国产噜噜麻豆| 国内精品久久久久影院免费| 99久久精品国产综合一区| 久久综合色区| 亚洲欧洲日产国码无码久久99|