青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

兔子的技術博客

兔子

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

留言簿(10)

最新評論

閱讀排行榜

評論排行榜

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

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


解決辦法:在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 會飛的兔子 閱讀(4227) 評論(0)  編輯 收藏 引用 所屬分類: 框架/圖像/算法
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美福利专区| 亚洲国产欧美一区二区三区久久 | 亚洲小少妇裸体bbw| 久久久国际精品| 国产一区在线视频| 国产伦精品一区二区三区在线观看 | 久久gogo国模啪啪人体图| 蜜臀a∨国产成人精品| 亚洲视频欧美视频| 久久视频在线免费观看| 国产精品va在线播放我和闺蜜| 亚洲国产精品热久久| 久久久夜色精品亚洲| 欧美高清影院| 亚洲视频观看| 欧美激情精品久久久久久变态| 亚洲三级电影在线观看| 亚洲经典一区| 亚洲精品国产系列| 久久精品国语| 老牛影视一区二区三区| 欧美色网一区二区| 亚洲第一中文字幕| 亚洲精选在线观看| 亚洲网站视频| 欧美日韩一区二区高清| 国产亚洲成人一区| 欧美一区二区久久久| 亚洲影院色无极综合| 欧美日韩一区高清| 亚洲精品国产系列| 亚洲国产成人av| 欧美日韩伦理在线| 香港成人在线视频| 午夜一级在线看亚洲| 国产欧美日韩亚洲精品| 久久爱www久久做| 欧美在线日韩精品| 在线精品高清中文字幕| 一本到高清视频免费精品| 国产精品欧美久久久久无广告| 久久久999精品免费| 久久久999国产| 夜夜嗨一区二区三区| 亚洲欧美日韩天堂| 最新精品在线| 一本在线高清不卡dvd| 一区在线观看视频| 亚洲精品久久嫩草网站秘色 | 午夜精品区一区二区三| 久久久久久综合网天天| 亚洲无人区一区| 欧美日韩免费观看一区三区| 亚洲国产日韩欧美一区二区三区| 在线免费观看成人网| 一区二区不卡在线视频 午夜欧美不卡'| 国产视频一区免费看| 亚洲免费视频在线观看| 篠田优中文在线播放第一区| 欧美韩日一区二区三区| 91久久综合亚洲鲁鲁五月天| 国语自产偷拍精品视频偷 | 亚洲国产小视频在线观看| 一区二区av在线| 久久av一区二区三区漫画| 夜夜嗨av一区二区三区网站四季av | 国产精品大片wwwwww| 欧美电影免费观看高清| 亚洲激情网址| 蜜臀av性久久久久蜜臀aⅴ| 久久亚洲影音av资源网| 国内精品久久久久久| 亚洲欧美成人一区二区在线电影| 亚洲精品乱码| 欧美日韩国产一区二区三区| 亚洲激情影视| 亚洲影视中文字幕| 国产精品国产福利国产秒拍| 午夜精品久久久久久久久久久久| 美女任你摸久久| 亚洲精品视频在线观看网站 | 91久久综合亚洲鲁鲁五月天| 欧美日韩视频专区在线播放| 午夜国产一区| 亚洲三级免费观看| 久久久久国产精品一区二区| 亚洲乱码视频| 亚洲电影欧美电影有声小说| 国产午夜精品全部视频在线播放| 欧美日韩在线不卡| 欧美日韩一区在线观看视频| 欧美人在线视频| 欧美国产精品劲爆| 欧美三级视频在线观看| 国产精品久久久久久亚洲调教| 蜜臀av国产精品久久久久| 亚洲在线视频免费观看| 亚洲精品乱码久久久久久蜜桃91| 91久久久国产精品| 久久久久久久久伊人| 在线亚洲成人| 亚洲国产高清aⅴ视频| 一区二区在线观看av| 欧美激情欧美狂野欧美精品| 亚洲综合第一页| 宅男在线国产精品| 91久久线看在观草草青青| 久久人人97超碰精品888| 日韩视频免费观看高清在线视频 | 亚洲国产精品激情在线观看| 国产精品久久久久7777婷婷| 久久漫画官网| 裸体一区二区三区| 久久全国免费视频| 久久这里有精品视频| 久久精品国产欧美激情| 麻豆乱码国产一区二区三区| 欧美在线免费视频| 欧美mv日韩mv亚洲| 亚洲三级网站| 亚洲欧美日韩成人| 久久久精品视频成人| 欧美日韩国产在线| 国产欧美精品日韩精品| 国产日韩亚洲欧美综合| 伊人久久综合| 亚洲国产婷婷综合在线精品| 一区二区日韩欧美| 久久免费精品日本久久中文字幕| 久久免费偷拍视频| 亚洲午夜一区二区| 亚洲欧美三级在线| 国产精品成人国产乱一区| 亚洲日本欧美在线| 久久久另类综合| 亚洲精品一区二区三区蜜桃久| 欧美一区二区精品| 欧美日韩精品免费观看视频完整| 国产精品成人va在线观看| 亚洲高清资源综合久久精品| 午夜欧美精品久久久久久久| 亚洲国产成人在线播放| 美女主播视频一区| 黑人操亚洲美女惩罚| 亚洲欧美在线高清| 一级成人国产| 欧美视频在线观看免费| 一区二区三区日韩精品视频| 亚洲国产老妈| 狼人社综合社区| 在线精品亚洲| 免费不卡亚洲欧美| 宅男66日本亚洲欧美视频| 欧美日韩123| 一级日韩一区在线观看| 亚洲日本免费电影| 欧美片在线播放| 亚洲一区国产精品| 久久九九免费| 亚洲精品久久久久久久久久久久久| 亚洲国产清纯| 亚洲一区二区欧美日韩| 狠狠狠色丁香婷婷综合激情| 欧美一级电影久久| 久久久久久国产精品mv| 亚洲国产精品嫩草影院| 欧美激情一区二区三级高清视频 | 亚洲私人影院在线观看| 国产乱码精品一区二区三区忘忧草 | 亚洲欧美日韩中文播放| 亚洲在线视频观看| 精品福利av| 亚洲视频中文| 国产精品99久久99久久久二8| 亚洲男人av电影| 日韩写真在线| 国产精品久久久久久久久久免费看 | 久久精品国产一区二区三| 亚洲欧美日韩成人| 国产视频欧美视频| 免费成人黄色片| 99国产精品99久久久久久| 亚洲欧美日韩精品久久奇米色影视| 欧美性天天影院| 久久国产色av| 亚洲视频碰碰| 亚洲电影中文字幕| 欧美老女人xx| 久久精品国产99精品国产亚洲性色 | 国产精品影视天天线| 亚洲人成网站999久久久综合| 亚洲电影av在线| 性欧美18~19sex高清播放| 亚洲精品社区| 香蕉av777xxx色综合一区| 伊人久久久大香线蕉综合直播 | 久久人人精品| 日韩视频一区二区三区| 国产日韩av一区二区| 欧美日韩国产三级|