你要写一个全局分配器是有道理的

来源:未知 更新时间:2011-07-11 11:37

    如果有一个类将会给你的内存造成碎片,那么这个类有可能是字符串。事实上,你甚至不需要一个类来这么做;只需要把字符t,函数,比如strdup()和fivt()组合起来.就可能会碰到麻烦。
    为什么字符串会给分配器带来麻烦呢?对于新手.它们通常很小而且它们的大小不同。如果你正用mauoc(踌口free()来使用许多一两个字节的字符串,那么你很快就会使得对管理器崩汤.
    但是.有一个更深入的相关的问题。如果有个程序员不喜欢使用不雅的函数比如strcmpO, strdupo闲   strcpy(),也不愿夹处理字符指针的泄漏问题,他写了一个字符串类。这样语法上看起来就很整洁了
string a = "hello';
Stri nob三a:
    现在.对于应该做什么有(至少有)两种观点。一种观点是,对于这个请求应该复制一个字符串。那就这么做吧,如下:strcpyib·而J(Mrptr, a.mJ瞬harPtr );
    但是.第二种观点认为这样做是浪费。如果b一直不变.为什么不用一个指针指向它呢,
    但是b发生变化会怎么样呢,是的,我们必须把a复制到b,然后更新bo这个策略叫做写复制(COW》.在很多情况下许多字符串类都要使用的。它打开了潘多拉盒子理的小虫路,因为宇符串类突然变成一个复杂的,有参考计数而且相当不稚定的一个东西,而不是我们所期望的高性能的小玩赚。
    如果我们要避免COW,我们就要使用这些宇符串,它们能够在创匆复制,调整的时候进行分配,在析构包括越界的时候进行释放。换句话说,字符串对内存管理系统会透成很大的影响,降低性能.出现碎片。C++能够在需耍的时候创建临时的对象,了解字符串行为的程序员可能会放弃使用字符串类,坚持使用醉态数组和C标准库接口的组合。不幸的是,这可能会放弃宇符串类应有的能力。比如,有一个哈希表将名字映射到对旅上
    这里的问题是,它会造成很大的浪费如果大部分字符串都是很短的,比如说是16到32个字符长度,那么我们会产生很多没用的存储空间。看起来不是很多,但是在项目的结束的时候你会弄得焦头烂额。
    我们容欢的解决方案是为字符串使用一组池分配器。从最小的字符串缓存长度(比如16)开始,我们为16个字符长度的字符串分配一个池。为kyj个字符的字符串分配另一个池.以此类推.直到字符串的最大长度。允许用户来控制每种长度的字符串的可分配的数目,我们可以约定字符出所储的内存的数且。我们可以根据游戏的字符串使用模式来定制这块内存的大小。
    字符串从这些池中分配它们的缓存。当增加字符串时,从池中分配一块最小的大小合适的块。因为字符串使用池分配器,字符串内存中不会出现碎片.分配和释放过程速度非常快。也没有恼人的指针问题,任务完成。
    上述的观点是这样:局部的对象分配策略要优于全局的。最后,我们的游戏是一组松辐合的组件。这样的独立性表示,如果我们在组件中解决了内存分配问题。那么全局的内存问坦也就轻松解决了。
    但是.总是有人认为事实并非如此。他们有自己的看法。他们说前面你要写一个全局分配器是有道理的。那样做并不会造成性能损失和碎片。事实上,只要分配策略严重依赖于你的使用模式.你就需要用某种机制来使用已有的分配胎以便于发现那些使用模式是什么。应该记录砂和delete的调用情况,这样你可以跟踪泄漏和多次删除的情况,而且可以了解你的游戏使用堆内存的情况。
    这些都是好的原因。但是,也应该用对项目的影响的大小来评估一下,它们造成的损失远大于收益。

找传奇私服,就来www.233dnf.com