深入解析内存池:理论与实践要点总结

更新:10-29 名人轶事 我要投稿 纠错 投诉

大家好,感谢邀请,今天来为大家分享一下深入解析内存池:理论与实践要点总结的问题,以及和的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!

内存池如何设计;如何设计字节对齐;如何设计统计内存使用情况; (待完成)如何设计单元测试来验证内存池的正确性。 (待完成)一些技术问题:

Malloc已经实现了内存对齐。如何实现以及如何证明? (未解决)free和delete是如何实现的,如何知道要释放多少内存。 (未解决)

一 如何设计内存池

内存池一般来说,大块内存是直接分配的,而小块内存则先申请一大块内存,然后继续使用这大块内存,直到用完为止。基本算法如下:

内联字符* Arena:分配(size_t字节){

//如果我们允许的话,返回内容的语义有点混乱

//0 字节分配,所以我们在这里不允许它们(我们不需要

//它们供我们内部使用)。

断言(字节0);

if (bytes=alloc_bytes_remaining_) { //是否可以从可用内存中获取

char* 结果=alloc_ptr_;

alloc_ptr_ +=字节;

alloc_bytes_remaining_ -=字节;

返回结果;

}

返回AllocateFallback(字节); //否,申请内存

不能从可用内存中获取大内存块。对于小块内存,需要查看剩余内存大小。如果剩余金额少于需求量,也需要申请。否则,无需申请。

因此,小内存共享大内存的使用情况需要通过以下两个变量来标识:

//分配状态

字符* alloc_ptr_; //大块内存的可用位置;

size_t alloc_bytes_remaining_; //当前大内存块还剩下多少?这简化了小内存块的分配。大块内存的分配逻辑如下:

char* Arena:AllocateFallback(size_t 字节) {

if (字节kBlockSize/4) {

//对象超过块大小的四分之一。单独分配

//避免在剩余字节中浪费太多空间。

char* 结果=AllocateNewBlock(字节);

返回结果;

}

//我们浪费了当前块中的剩余空间。

alloc_ptr_=分配新块(kBlockSize);

alloc_bytes_remaining_=kBlockSize;

char* 结果=alloc_ptr_;

alloc_ptr_ +=字节;

alloc_bytes_remaining_ -=字节;

返回结果;

}

char* Arena:AllocateNewBlock(size_t block_bytes) { //所有申请内存的操作都在这里;

char* 结果=new char[block_bytes];

block_.push_back(结果);

memory_usage_.NoBarrier_Store(

reinterpret_cast(MemoryUsage() + block_bytes + sizeof(char*)));

返回结果;

}申请大块内存有两种情况:

(1)用户自行申请大内存;

(2)用户申请了小内存,但是小内存使用的大内存块已经用完。

对于第一种情况,直接调用AllocateNewBlock方法,申请那块大内存,交给用户即可。

对于第二种情况,调用AllocateNewBlock方法申请固定大小内存(kBlockSize)后,还需要设置alloc_ptr_和alloc_bytes_remaining_变量;最后在这个新申请的大内存中给用户分配内存。

内存的释放是一起执行的,位于分配器的析构函数中:

竞技场:~竞技场() {

for (size_t i=0; i 块_.size(); i++) {

删除[]块_[i];

}

}blocks_ 定义如下:

//new[] 分配的内存块数组

std:vectorblocks_;blocks_包含AllocateNewBlock方法申请的所有内存,最终被统一释放。

一些问题:

小内存共享的大内存块有多大,即一次申请多大的大小合适? (相关的论文查询)

这是leveldb 中的大小: static const int kBlockSize=4096;应该申请多少内存并直接返回给用户,而不是共享一个大内存块?

这又分为两种情况:

(1)当有大块内存可用时,只要大块内存足够,就会直接返回给用户;

(2)当没有可用的大块内存,并且超过kBlockSize的1/4时,直接申请相应大小的内存并返回给用户,而不是申请kBlockSize大小的内存作为小内存。

上述策略涉及到内存的浪费,具体如下:

当用户新申请的内存不在可用内存大小范围内且小于kBlockSize时,则该段可用内存被浪费,并申请新的内存,alloc_ptr_从新的内存开始。

内存是最后统一释放的,那么有没有什么策略需要提前释放以节省内存呢?具体发布时间是什么时候?

二 如何设计字节对齐

malloc分配的内存必须是对齐的,也就是说返回的地址必须是2的幂(内存对齐的大小一般是指针的大小,指针的大小必须是2的幂)。

那么如何找到对齐的尺寸align:

const int 对齐=(sizeof(void*) 8) ? sizeof(void*) : 8;对齐后的地址必须满足(align - 1的值中1的个数代表返回值指针中最后一个0的个数):

断言((reinterpret_cast(结果)(align-1))==0);具体算法如下:

char* Arena:AllocateAligned(size_t 字节) {

const int 对齐=(sizeof(void*) 8) ? sizeof(void*) : 8;

断言((对齐(align-1))==0); //指针大小应该是2的幂

size_t current_mod=reinterpret_cast(alloc_ptr_) (align-1); //alloc_ptr_的最后n位,n为对齐的位数

size_t slop=(current_mod==0 ? 0 : 对齐- current_mod); //对齐所需的空闲字节数

所需的size_t=字节+ slop;

字符* 结果;

if (needed=alloc_bytes_remaining_) { //与上一节中的Allocate类似

结果=alloc_ptr_ + slop;

alloc_ptr_ +=需要;

alloc_bytes_remaining_ -=需要;

} 别的{

//AllocateFallback 总是返回对齐的内存

结果=AllocateFallback(字节); //对malloc的调用必须是内存对齐的;

}

断言((reinterpret_cast(结果)(align-1))==0);

返回结果;

}函数也分为两部分进行处理:

(1)申请内存大小+对齐字节数。可用内存大小。这时候直接调用malloc申请(这样可能会造成内存的浪费)。这时候就必须进行内存对齐;

(2)申请内存大小+对齐字节数、可用内存大小、手动对齐:调整alloc_ptr_到对齐位置,然后调整alloc_ptr_到下一个可用位置作为返回结果。对齐的结果与返回值对齐,最终的alloc_ptr_没有对齐。

用户评论

ゞ香草可樂ゞ草莓布丁

最近在研究内存管理,发现内存池真是个好东西!

    有5位网友表示赞同!

抚涟i

想要了解一下内存池的使用方法,感觉可以提高程序效率。

    有8位网友表示赞同!

鹿先森,教魔方

之前不太了解内存池,标题很吸引人,一定要看看!

    有9位网友表示赞同!

微信名字

看文章总结的文章总 feels 好懂,就是想知道应用场景多多!

    有15位网友表示赞同!

我要变勇敢℅℅

这篇文章的思路很有深度,让我对内存池有了更深的认识。

    有16位网友表示赞同!

最怕挣扎

我一直用默认的内存管理方法,这个内存池应该是个很好的优化选择吧?

    有18位网友表示赞同!

冷青裳

学习一下内存池的使用技巧,说不定能帮到我做算法。

    有9位网友表示赞同!

我怕疼别碰我伤口

分享一篇和内存池相关的文章,感觉很实用!

    有9位网友表示赞同!

£烟消云散

作者观察角度真是独特,分析得也挺到位。

    有12位网友表示赞同!

伱德柔情是我的痛。

这篇文章给我的启发很大,对内存管理有了更清晰的理解。

    有10位网友表示赞同!

一尾流莺

看这种总结类的文章确实方便,可以快速了解关键信息。

    有12位网友表示赞同!

百合的盛世恋

学习一下内存池和性能优化之间的关系,很有价值!

    有17位网友表示赞同!

淡淡の清香

分享给正在学习C++的朋友,可能对他们很有帮助。

    有16位网友表示赞同!

为爱放弃

感觉内存池这个概念真挺有趣的,让我想要深入探索一下。

    有18位网友表示赞同!

暮染轻纱

看标题就能明白文章内容,期待了解作者的观点和总结。

    有10位网友表示赞同!

醉婉笙歌

内存管理一直是重要的基础知识,学习这种优化方法确实好!

    有14位网友表示赞同!

┲﹊怅惘。

作者分析比较透彻,对不同类型的应用场景有针对性的探讨很实用。

    有6位网友表示赞同!

歇火

感觉这篇文章适合作为学习内存池的入门资料。

    有15位网友表示赞同!

爱你心口难开

很有意思的文章,让我对内存管理有了新的认识。

    有16位网友表示赞同!

【深入解析内存池:理论与实践要点总结】相关文章:

1.蛤蟆讨媳妇【哈尼族民间故事】

2.米颠拜石

3.王羲之临池学书

4.清代敢于创新的“浓墨宰相”——刘墉

5.“巧取豪夺”的由来--米芾逸事

6.荒唐洁癖 惜砚如身(米芾逸事)

7.拜石为兄--米芾逸事

8.郑板桥轶事十则

9.王献之被公主抢亲后的悲惨人生

10.史上真实张三丰:在棺材中竟神奇复活

上一篇:揭秘邀请码:填写方法与用途详解 下一篇:传奇故事:司马飞燕第二节