微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 改进分配器算法实现的建议

我有一个Visual Studio 2008 C应用程序,我正在为标准容器使用自定义分配器,以便它们的内存来自内存映射文件而不是堆.此分配器用于4种不同的用例:

> 104字节固定大小的结构std :: vector< SomeType,MyAllocator< SomeType> > FOO;
> 200字节固定大小的结构
> 304字节固定大小的结构
> n字节字符串std :: basic_string< char,std :: char_traits< char>,MyAllocator< char> > STRN;

我需要能够为这些中的每一个分配大约32MB的总和.

分配器使用指向分配大小的std :: map来跟踪内存使用情况. typedef std :: map< void *,size_t>超级;每个SuperBlock代表4MB内存.

一个std :: vector<超级块>其中一个超级块没有足够的空间.

用于分配器的算法如下:

>对于每个SuperBlock:SuperBlock末尾是否有空格?把分配放在那里. (快速)
>如果没有,在每个SuperBlock中搜索足够大的空白空间并将分配放在那里. (慢)
>什么都没有?分配另一个SuperBlock并将分配放在新SuperBlock的开头.

不幸的是,一段时间后,第2步可能变得非常缓慢.随着对象的复制和临时变量的破坏,我得到了很多碎片.这导致在存储器结构内进行大量深度搜索.碎片存在问题,因为我使用的内存有限(请参阅下面的注释)

任何人都可以建议改进这种算法来加速这个过程吗?我需要两个单独的算法(1个用于固定大小的分配,1个用于字符串分配器)?

注意:对于那些需要理由的人:我在Windows Mobile中使用此算法,其中Heap有32MB的进程槽限制.所以,通常的std :: allocator不会削减它.我需要将分配放在1GB大内存区域中以获得足够的空间,这就是它的作用.

解决方法

对于固定大小的对象,您可以创建固定大小的分配器.基本上,您可以分配块,将分区分配到适当大小的子块中,并使用结果创建链接列表.如果有可用内存(仅从列表中删除一个元素并返回指向它的指针),则从这样的块分配是O(1),因为是解除分配(将块添加到空闲列表).在分配期间,如果列表为空,则获取新的超级块,分区并将所有块添加到列表中.

对于可变大小的列表,您可以通过仅分配已知大小的块来将其简化为固定大小的块:32字节,64字节,128字节,512字节.您将不得不分析内存使用情况以提出不同的存储桶,这样您就不会浪费太多内存.对于大型对象,您可以返回动态大小分配模式,这将很慢,但希望大对象的数量有限.

原文地址:https://www.jb51.cc/c/117041.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐