<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Ogre中的內存泄露

    剛開始使用Ogre時總是碰到內存泄露,而且往往是一泄千里,等半分鐘才能打完日志,我想這和Ogre中的大量大對象很有關系。下面就來分析一下內存泄露的產生原因。

    1. MFC中使用Ogre時發生的內存泄露

    這個問題比較有意思,其實并沒有發生泄露,而是MFC自作主張的認為發生了內存泄露,實際上內存并不是沒有釋放,而是在VC報內存泄露之后釋放,先來看一看MFC報內存泄露時的調用堆棧:

    msvcr71d.dll!_CrtDumpMemoryLeaks() 行2208 C
    mfc71d.dll!_AFX_DEBUG_STATE::~_AFX_DEBUG_STATE() 行127 C++
    mfc71d.dll!_AFX_DEBUG_STATE::`scalar deleting destructor'() + 0xf C++
    mfc71d.dll!CProcessLocalObject::~CProcessLocalObject() 行472 + 0x26 C++
    mfc71d.dll!CProcessLocal<_AFX_DEBUG_STATE>::~CProcessLocal<_AFX_DEBUG_STATE>() + 0xf C++
    mfc71d.dll!$E10() + 0xd C++
    mfc71d.dll!_CRT_INIT(void * hDllHandle=0x7c140000, unsigned long dwReason=0, void * lpreserved=0x00000001) 行234 C
    mfc71d.dll!_DllMainCRTStartup(void * hDllHandle=0x7c140000, unsigned long dwReason=0, void * lpreserved=0x00000001) 行288 + 0x11 C

     

    AFX_DEBUG_STATE的析構函數:

    _AFX_DEBUG_STATE::~_AFX_DEBUG_STATE()
    {
    #ifndef _AFX_NO_DEBUG_CRT
    _CrtDumpMemoryLeaks();
    int nOldState = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    _CrtSetDbgFlag(nOldState & ~_CRTDBG_LEAK_CHECK_DF);

    _CrtSetReportHook(pfnOldCrtReportHook);
    _CrtSetDumpClient(pfnOldCrtDumpClient);
    #endif // _AFX_NO_DEBUG_CRT
    }

    很顯然CrtDumpMemoryLeaks()是在mfc71d.dll卸載時被調用的,如果這個時候OgreMain_d.dll還沒有卸載,那么在Ogre中new的全局變量也就還沒有釋放,所以MFC會認為產生了內存泄露。如何處理這樣的問題呢。很簡單,讓OgreMain_d.dll在mfc71d.dll之前析構,但是默認的MFC程序似乎不是這樣干的(為什么呢?),這就要求對項目設置作一點調整,使得Mfc71d.dll在OgreMian之前被鏈接,這樣程序運行時MFC71d就會早于Ogre加載,也就晚于Ogre卸載。具體設置如下:

    i) in the General tab, switch "Use MFC in a shared DLL" to "Use Standard Windows Libraries"
    ii) in the C/C++/Preprocessor tab, add _AFXDLL to the preprocessor definitions
    iii) in the Linker/Input tab, add mfc80d.lib anywhere before OgreMain_d.lib

    另一種方法是,使用Ogre自己的MemoryManager,并且禁止調用MFC的DEBUG_NEW,這需要先

    #define OGRE_DEBUG_MEMORY_MANAGER 1

    然后刪除cpp中的以下行

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif

    這樣Ogre中會使用自己的new/delete,而不是調用vccrt中的_heap_alloc_debug

     

    2. Ogre中的對象沒有釋放

    由于Ogre中的很多對象并不是只要delete Root就可以釋放的。最好所有的對象都不要自己new,而是通過Ogre::Root,Ogre::SceneManager等創建,這些對象在Root析構時會自己銷毀,但是對于從Ogre類派生的類,由于Ogre不存在Create這些類的函數,所以只能在自己的代碼中new產生,并由自己負責析構了,比如MovableObject派生的MovableText。當然Ogre也會給你一個將新對象加入其管理的接口,對于MovableText就必須再實現一個MovableTextFactory才行。總之要小心小心再小心。

    最后抱怨一下Ogre太大了,有一個OgreLite就好了。現在這樣使用起來光鏈接都要半天,真是太夸張了,所以沒事最好不要修改Ogre庫,呵呵。

    posted on 2007-06-17 16:44 雁過無痕 閱讀(4742) 評論(5)  編輯  收藏

    評論

    # re: Ogre中的內存泄露 2008-11-18 10:30 AlexQ

    很管用 謝謝  回復  更多評論   

    # re: Ogre中的內存泄露 2009-01-02 01:33 geeeeeeee

    按第一種方法有如下錯誤
    1>msvcrtd.lib(crtexew.obj) : error LNK2019: 無法解析的外部符號 _WinMain@16,該符號在函數 ___tmainCRTStartup 中被引用  回復  更多評論   

    # re: Ogre中的內存泄露 2009-01-02 01:34 geeeeeeee

    可能是UNICODE問題不知如何解決  回復  更多評論   

    # re: Ogre中的內存泄露 2009-07-26 16:22 yyyy

    謝謝,我也正好遇到此問題,按你的方法解決了  回復  更多評論   

    # re: Ogre中的內存泄露 2012-08-31 15:08 Carefree

    你好,不知道現在樓主還研究OGRE么?
    我用ogre1.8也遇到了內存泄露的問題,但按樓主的辦法沒有效果。  回復  更多評論   


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2008年11月>
    2627282930311
    2345678
    9101112131415
    16171819202122
    23242526272829
    30123456

    導航

    統計

    常用鏈接

    留言簿(7)

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲人成电影在线观看青青| 亚洲国产精品久久久久婷婷软件 | 一级做a爰片久久免费| 国产在线国偷精品产拍免费| 亚洲人成影院午夜网站| 久视频精品免费观看99| 婷婷精品国产亚洲AV麻豆不片| 99精品视频在线观看免费| 日日噜噜噜噜夜夜爽亚洲精品| 九九热久久免费视频| 亚洲宅男天堂在线观看无病毒| 亚洲精品视频免费| 中文字幕亚洲不卡在线亚瑟| 女人隐私秘视频黄www免费| 国产乱辈通伦影片在线播放亚洲| 边摸边脱吃奶边高潮视频免费| 亚洲精品成人久久久| 亚洲一区二区三区免费| 亚洲日韩小电影在线观看| 久久精品视频免费| 久久亚洲sm情趣捆绑调教| 亚洲第一网站免费视频| 亚洲一久久久久久久久| 四虎影视永久免费观看地址| 成人福利在线观看免费视频| 亚洲av中文无码乱人伦在线播放| 久久精品成人免费观看| 亚洲日韩在线视频| 日韩伦理片电影在线免费观看| 美女黄色毛片免费看| 亚洲AV无码一区二区二三区入口 | 麻豆亚洲av熟女国产一区二| 日本XXX黄区免费看| 国产精品久久亚洲一区二区| 亚洲精品成人片在线观看精品字幕| 24小时免费看片| 精品一区二区三区免费毛片| 久久香蕉国产线看观看亚洲片| 女人让男人免费桶爽30分钟| 99精品免费视品| 亚洲成在人线在线播放无码 |