网站大量收购闲置独家精品文档,联系QQ:2885784924

0bug商用之道笔记-第7章 内存及资源管理课件.docx

0bug商用之道笔记-第7章 内存及资源管理课件.docx

  1. 1、本文档共31页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
不泄露:如果在C 和C++传统的内存管理机制之外,我们自行构建一种内存?的管理机制,能在程序员忘了释放内存时,主动替其释放,则可望大大减少内存相关的bug。?因此,内存池的第一个设计目标,是主动替程序员完善二元动作,确保“不泄露内存”。?针对这个问题,笔者通常的解决方案是内部建立一套登记机制,记录所有在用的内存块,当程序退出时,如果发现还有内存块在内存池中处于激活状态,即表示有内存块忘了释放,内存池会帮助程序员释放内存,避免产生内存泄漏。不产生碎片:从前文我们知道,内存碎片的根源,在于一个程序,无序地申请任意大小的内存,最?后导致系统堆上的内存不连贯,虽然从统计上得知,还有足够的内存空间,但这是由小块的内存区域组成,没有足够的,整块的大型空间,使后续的大块内存申请无法成功,导致服务无法继续。笔者经过思考,总结了如下几条推论,以此来试图控制内存碎片的产生:1、一个应用程序,总的来说,其使用的所有内存,不会超过其目标运行平台的基本内?存空间,这很好理解,每个程序员做程序,总是能预估自己的程序,需要多大内存,因此,?在产品说明书上,会提示用户准备足够内存的计算机。?2、由上可知,我们在动态内存块可以重用的前提下,可以利用一套机制,屏蔽内存区?的动态释放工作,即所有的动态内存,一旦申请,在本次运行期不再释放,这并不会导致计算机内存溢出。?3、动态内存块可以重用,需要保证两点,首先是有一套管理机制,可以记录申请和释?放的所有内存块,把释放的内存块二次提供给新的内存申请使用,其次,必须对内存块取模,减小内存块的种类,提高内存块的可重用性。关于取模的原则和方法,我们后文讨论。可以自动报警:经过思考,笔者的内存池所有的内存申请动作,全部改为如下格式:MemPool.Malloc(int nSize,char* szInfo);这里的szInfo,是笔者规定的124Bytes 的说明性文字,强迫所有申请内存的模块,必?须在其中声明自身的身份,一旦发生泄漏,任何一次运行完毕,内存池析构时,立即会打印出相关的信息,程序员即可实现快速查找。内存池的核心逻辑—内存栈:内存管理的数学模型:内存块如果要提升可重用性,必须对内存块尺寸进行取模,否则的话,很容易因为几?个Bytes 的偏差,导致内存块无法重用,被迫向系统频繁申请新的内存空间,那意义就不大了。?取模的主要目的,是减少内存块的种类,以有限几个尺寸的内存块,应对绝大多数内?存使用要求。笔者仿造STL 的取模方式,在内存池中按照如下逻辑取模,简单说来,就是从16Bytes?开始,以两倍方式递增模数。直到4G 内存为止。当然,实际使用时,超过1M 的内存块,一般应用很少,即使有,基本上也属于应用程序永久缓冲区,很少会中途频繁释放,因此,笔者的内存池管理,一般模数为16Bytes~1M 即可。管理原则:分配时,首先在合适的右枝寻找可用的内存块,如果有,则直接分配给应?用程序重用该块,如果没有,则向系统申请一块64Bytes 的内存块,分配给应用程序使用。而当应用程序释放时,内存块本身是64Bytes 的,因此,可以直接挂回到64Bytes 这根右枝,等待下次重用。管理模型的优化:虽然上文我们讨论的是以链表方式管理,不过,在实做中,笔者发现一个问题,即链?表效率不高,原因很简单,笔者的链表是以队列方式管理,每次从右枝取出内存块,是从链表头取出,但释放时,将内存块推回右枝,需要循环遍历到链表尾部进行挂链操作。这在高速的内存申请和释放时,会严重影响链表的效率。?笔者经过思考,发现一个问题,当一个内存块被推回一个右枝,其实已经是无属性的,?比如,64Bytes 这个右枝上,挂的都是64Bytes 大小的内存块,应用程序申请时,使用任何一块都是可以的,无需考虑这块是在链头还是链尾,同时,申请的内存块,都是需要初始化的,应用程序也不关心这块内存块是否刚刚被使用完,还是已经空闲很久了。笔者理解这个内存树的右枝,其实已经是前文所说的“被动池”逻辑了。我们知道,在“推”入和“提取”这个逻辑上,“栈”的效率远高于“队列”,通常?我们不使用栈的唯一原因,主要是栈是“后进先出”逻辑,而队列是“先进先出”逻辑。但此处既然我们已经明确论证了,内存块无顺序需求,那么,我们完全可以使用栈模?型来管理内存树的右枝,以提高效率。正因为如此,笔者才将内存池最核心的内存管理模块,定名为内存栈(Memory Stack)typedef struct _TONY_MEM_BLOCK_HEAD_{? ? ULONG m_ulBlockSize; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//内存块的尺寸? ? struct _TONY_MEM_BLOCK_HEAD_* m_pNext; ? ? ? //指向

文档评论(0)

xuefei111 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档