盗賊の極意

Feed Rss

内存使用量追踪记(一)

09.13.2013, 未分类, by , 6,853 views.

经过了百无聊赖的8月,9月初公司终于给了我一个新任务——找出现在正在开发的游戏中的内存峰值的出现位置,然后想办法解决一下。

上司的意思是,这是个体力活,你在源代码各处看看都哪里在读取2D3D资源文件,数数看大概用了多少内存,可我当时听到这个任务的时候心里想的是“这个活儿NB啊,我要做内存分布追踪工具!”

不是我好高骛远,这里确实是这个道理。你看,我们副部长搞那个精简分散内存开支的活儿已经不是一天两天了,他都搞不定,我们下面的小喽罗想凭运气找出这个内存瓶颈就更困难了,何况我还不了解各处是以什么习惯在申请和释放内存(比如说,每次用之前申请用完释放,还是进入界面前一口气都申请了,之后就不管了)。

反正就是这么回事。开工吧。

先在网上搜了一圈,大概看了一下内存用量追踪的做法,然后锁定了这篇文章 《Monitoring Your PC's Memory Usage For Game Development》。不仅是内存使用量侦测,而且正好是应用于游戏开发,内容难易度也在我可以理解和实现的范畴之内,开心~

 

『当初我庆幸自己一下就找到了实用教程的时候,还没有想到之后的路会这么的难走……』

内存使用量追踪记(一) 有 2 条回应

  1. 内存分布追踪工具听名字就觉得很厉害,但是大长篇英文看着太辛苦,期待下一篇科普技术要点。

    回复
  2. 2013-09-17 在 15:04 基拉铃妖

    好久不见>_<

    简单剧透一下,那篇文章里介绍了两个内存追踪的方法。
    一个是自己写operator new()和operator delete(),替换掉系统默认的,然后在里面做些记录。这个方法比较简单,但是链接使用的库文件因为看不到源码,无法替换里面的new。另外像Directx3D之类的库里面除了new,还会用些malloc呀HeapAlloc之类的函数直接分配内存,这里就需要配合第二种方法:windows Hook了。
    原文介绍了两种windows hook库,一个是微软自己的商业版要收费且据说免费版不支持64位系统的Detours库(有的游戏公司招程序员还要求会用这个库的人优先),另一个是个人写的开源免费支持64位的mhook库。那篇文章的作者推荐了mhook,所以Detours我没看,mhook里面有一个示例代码,我编译运行以后是一切正常的,看起来用法也挺简单,不过我还没进行到那么深入的地方,所以还没实际用过mhook。

    然后是数据储存。直接存储在要调查的程序上的话,可能导致它内存使用量过量,或者因为额外负担太重所以表现和平时不同什么的,所以作者的做法是在要调查的程序内嵌入信息收集和发送端,然后另作一个GUI的接收端,两者用网络端口通信。这个我做出来以后自己都觉得超NB的,可以在另一台机器上远程监控程序,而且被调查的程序增加的负担非常小,表现和平时运行一样。

    关于发送和接受的信息,我自己是保存了申请的内存的指针和大小和调用栈上各层的函数名。获取函数名的方法作者已经给出了现成的代码,直接复制粘贴用之。
    不过我用的数据结构好像不太好,所以保存的函数乘以指针数超过10万以后,查询信息和处理释放内存什么的就变得特别的慢,慢到无法接受,内存使用量也变得太高。我现在是用两个std::mutlimap来保存函数到指针和指针到函数的信息,算他指针8byte,调用栈每层4byte*21层,内存大小8byte,每个map里20W条,加一加也不超过40MB吧,可实际上接收端程序经常占用数百MB的内存,我猜是std::multimap里有很多我不需要的功能。如果这个瓶颈实在无法克服的话,可能需要自己写一个简单的容器了。

    上周一直在借公司工作的理由研究这个,这周不得不加速干点正事,所以内存追踪的研究要暂停一阵子了。

    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>