游戏开发中预防内存泄露的一些措施

原创 2011年01月15日 22:03:00

在OpenRO项目过程中,遇到了一些Memory Leak的问题,采取了一些预防措施后,发现有利也有弊,在此总结一下。

关于内存泄露,最共性的就是new一个内存块后忘记delete了,对此,我介绍2个措施,shared_ptrDEBUG_NEW

一,shared_ptr:

这是boost库里的引用计数指针,它的好处是,把资源的释放交给shared_ptr管理,只要内存中存在指针的引用,该指针就不会被释放。通常shared_ptr在程序中是随处复制,拷贝的,之后引用计数增加。每个shared_ptr的作用域完后,引用计数又减少,如果某个引用计数减少为0,则释放该资源。

下面是一个例子:

void otherFunction(shared_ptr param);
std::list< shared_ptr > intList;
for (int i=0; i<100; ++i)
{
intList.push_back(shared_ptr(new int(rand())));
}

otherFunction(intList.pop_front());

显而易见,我们完全不用管int指针的资源释放,shared_ptr可以随处传递:intList与otherFunction等等。

缺点:可以看到,用了shared_ptr后,则程序对它的依赖性过大,任何声明都是shared_ptr xxxx,比如函数参数。还有一个缺点是,绝对不要两个对象互相引用,比如class A含有shared_ptr,而class B又含有shared_ptr。这样你就把它搞晕了,不晓得释放谁,最终结果就是2个资源都不会释放。

二,DEBUG_NEW

这是我在金山实习时学到的,VC下可以设置内存泄露检查机制,配合new的重定义,可以很好的预防内存泄露的问题。因为这组代码网上随处可下载,所以也就不涉及啥机密了,使用方法及代码我贴在文章末尾

不足:貌似没有。。。

三,Direct3D里的资源释放

这个与内存泄露不同,因为D3D里的资源大都是通过Create*()函数创建的,而且涉及COM的引用计数机制,所以shared_ptr与DEBUG_NEW对它不起作用。虽然D3D自带有泄露检查机制,程序退出时有弹窗提示,但是遗憾的是它仅仅是提示,不会告诉你哪里的资源没释放。至于预防,除了小心外,还有一些经验:

一,不仅仅是Create*()系列函数会增加资源的引用计数,某些Get*()系列函数也会增加资源的引用,比如:GetBackBuffer()获得Surface后,使用完毕必须Realease(),这是最容易忽略的地方,其实这些容易出错的地方,一般在MSDN里的"Remarks”栏有专门注明,所以看MSDN一定不要错过"Remarks“栏。

二,DX自带了Debug工具,一定程度上会帮助你调试资源泄露,具体我就不详细说明了,找到这个工具照着界面操作就行了,比如我电脑上的路径是:Utilities/bin/x86/dxcpl.exe


下面贴一个检测内存泄露的Debug Header,使用方法见注释。

/* -------------------------------------------------------------------------
//    文件名        :    debugnew.h
//    创建者        :    金山训练营
//    创建时间    :    2007-12-29
//    功能描述    :    辅助检查内存泄漏
//
//    修订记录:
//  1. 创建: 2007.12.29.
//
//  说明: 若使用了MFC则不必使用本文件. MFC有自己的检查内存泄露机制.
//
//    使用步骤:
//    1. include此文件.
//
//    2. 在.cpp中增加以下定义:
//        #ifdef _DEBUG
//        #define new DEBUG_NEW
//        #endif
//
//    3. 在程序退出后, 检查VC的output窗口内是否有dump memory leak
//
//    $Id: $
// -----------------------------------------------------------------------*/

#ifndef __DEBUGNEW_H__
    #define __DEBUGNEW_H__

    #ifdef  __cplusplus

        #ifndef _DEBUG
            // release版下不做任何事情
        #else
            // debug版下重定义new, 以便当出现内存泄漏时自动报警
            #include

        //    #ifndef TCHAR
        //        #if defined(_UNICODE) || defined(UNICODE)
        //            typedef wchar_t TCHAR;
        //        #else
        //            typedef char TCHAR;
        //        #endif
        //    #endif

            inline void * __cdecl operator new(unsigned int size,
                                               const char *file, int line)
            {
                int nFlag = _CrtSetDbgFlag (_CRTDBG_REPORT_FLAG);
                nFlag |= _CRTDBG_LEAK_CHECK_DF;
                _CrtSetDbgFlag (nFlag);
                return ::operator new(size, _NORMAL_BLOCK, file, line);
            };
            #define DEBUG_NEW new(__FILE__, __LINE__)
            //#define new DEBUG_NEW

            // 若不同时定义delete, 则在编译时会出现warning
            inline void __cdecl operator delete(void* pData,
                                                 const char* /* lpszFileName */,
                                                 int /* nLine */)
            {
                ::operator delete(pData);
            }

        #endif    // #ifndef _DEBUG
    #endif    // #ifdef  __cplusplus
#endif    // #ifndef __DEBUGNEW_H__

  • 本文已收录于以下专栏:

Android中内存泄露与如何有效避免OOM总结

Android系统为每个应用程序分配的内存有限,当一个应用中产生的内存泄漏比较多时,就难免会导致应用所需要的内存超过这个系统分配的内存限额,这就造成了内存溢出而导致应用Crash。内存泄露的危害:只有...
  • gjnm820
  • gjnm820
  • 2016年06月03日 15:09
  • 4196

内存泄漏以及常见的解决方法

之所以撰写这篇文章是因为前段时间花费了很大的精力在已经成熟的代码上再去处理memory leak问题。写此的目的是希望我们应该养成良好的编码习惯,尽可能的避免这样的问题,因为当你对着一大片的代码再去处...
  • lixingying567
  • lixingying567
  • 2015年06月13日 11:18
  • 6923

5个Android开发中比较常见的内存泄漏问题及解决办法

5个Android开发中比较常见的内存泄漏问题及解决办法 jy02571668 | 2015-12-08 11:31    浏览量(1285)    评论(6)   推荐(1) 数据 ...
  • q178266871
  • q178266871
  • 2016年02月22日 21:23
  • 7332

游戏开发中内存泄露的一些防范措施

在OpenRO项目过程中,遇到了一些Memory Leak的问题,采取了一些预防措施后,发现有利也有弊,在此总结一下。 关于内存泄露,最共性的就是new一个内存块后忘记delete了,对此,我介绍2...
  • zhu339111520
  • zhu339111520
  • 2014年02月28日 03:51
  • 655

Java中关于内存泄露出现的原因和避免措施

Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所...
  • zxllynu
  • zxllynu
  • 2017年11月06日 21:36
  • 78

防止 Java 内存泄露的安全措施

Java 通过 GC(一个守护进程)隐性回收内存资源。GC 会定期检查有没有哪个对象是不可达的,准确来说,没有引用指向这个对象。如果有,GC 就会回收这块内存。 现在的问题是我们应不应该担心内存...
  • zy_281870667
  • zy_281870667
  • 2016年09月14日 09:20
  • 460

提高Java开发质量之内存泄露

  • 2007年10月04日 11:43
  • 25KB
  • 下载

嵌入式开发调试内存泄露的一种方法

  • 2015年09月24日 21:03
  • 75KB
  • 下载

【手机游戏开发优化篇】详解手游[体积]及[运行内存]的优化篇!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:(作者新浪微博: @李华明Himi )  转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/an...
  • yang3wei
  • yang3wei
  • 2014年07月21日 10:37
  • 1162

11、Cocos2dx 3.0游戏开发找小三之3.0中的内存释放心法与辅助宏

通过前面的了解知道,在使用 autorelease()可以达到与 release()同样的效果, 甚至还能避免 release() 的许多隐患的情况下,是不是应该完全用 autorelease()代...
  • danielzzu
  • danielzzu
  • 2014年05月30日 19:22
  • 2537
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:游戏开发中预防内存泄露的一些措施
举报原因:
原因补充:

(最多只允许输入30个字)