当前位置: 首页> 文旅> 艺术 > 建网站需要多长时间_兰州网站分类导航_seo品牌优化百度资源网站推广关键词排名_自己开网店怎么运营

建网站需要多长时间_兰州网站分类导航_seo品牌优化百度资源网站推广关键词排名_自己开网店怎么运营

时间:2025/7/14 8:40:57来源:https://blog.csdn.net/Striveforsublime/article/details/145912068 浏览次数:0次
建网站需要多长时间_兰州网站分类导航_seo品牌优化百度资源网站推广关键词排名_自己开网店怎么运营

1.什么是高并发内存池?

首先来介绍一下这个项目 , 当前项目的目的是模拟实现一个高并发的内存池 , 他的原型是谷歌开源的一个项目 "tcmalloc" , 即是线程缓存的malloc , 实现了高效的多线程内存管理 , 用于替代系统的内存分配相关的函数(malloc , free)

我的目的就是把这个精华拿出来 , 模拟实现一个自己的高并发内存池 , 目的就是学习tcmalloc的精华.

1.池化技术

所谓"池化技术" , 就是程序向系统申请一块过量的资源 , 然后自己管理 , 以备不时之需.为什么要这也干呢?因为每次申请该资源都有较大的开销 , 不如提前申请 , 这也使用的时候就会非常方便 , 提高程序的运行效率.

这也就是高并发内存池的中心思想.

而在今天的博客当中 , 首先是实现一个定长的内存池 , 先简单熟悉一下内存池是如何去控制的 , 然后后面再把这个作为后续实现内存池的一个组件

2.实现高并发内存池

1.整体的设计思路

既然是设计一个定长的内存池 , 那么首先就要有一个申请下来的定长资源 , 然后用一个指针去指向这个资源 ; 然后如果是需要被程序申请拿去用的话 , 那么那一块被申请下来的内存就需要被一个自由链表给收集 , 以便后续的返还.

2.申请空间

那既然我们需要一个指针来指向一个定长资源 , 那么这个指针的类型设计为了方便后续的计算和维护 , 就需要一个char类型的指针 , 然后自由链表就需要一个void来指向他,除此之外 , 还要加一个剩余的空间字节大小 , 方便后续的维护

那么此时就应该来向系统来申请一块空间了

此时的_memory内存池一开始那必定是指向NULL的 , 所以我们一开始就可以这样写

由于后续的使用是每次都可能要申请sizeof(T)大小的空间来进行使用 , 所以我们一开始就可以把_memory指针往后移动sizeof(T)的位置 , 然后让前面一段内存指向obj , 而生成的空间大小我们又可以直接让_reaminBytes来进行接管 , 所以我们只需要malloc(_remainBytes)这么多的空间就可以了 , 既然_memory往后加了T的字节 ,那么相应的_remainBytes的剩余字节也得减少

此时的指针指向情况是这样的

我来解释一下 , 首先_memory是指向整个空间的第一个地址 , 然后我让obj指向了这个_memory , 此时就变成了obj指向了整个空间的第一个地址 , 然后我让_memory往后走T大小的字节 , 那也就是说 , 当前真正指向整个空间大小的就是_memory , 而前面的那一块内存 , 则是随时准备被申请的空间.

插一个细节 , 在上面的代码中 , if的判断条件是_memory是否是空指针 , 然后下面的_memory是直接+=一个sizeof(T)的 , 那么如果当一个T并不是4/8这些可以被128整除的数 , 而是3/5这类的数字 , 那么他每一次切的内存切到最后 , 他一定会剩余一些内存 , 而那些内存一定是不够一个T的大小的 , 那么这个时候 , 当每一次要来New()的时候 , 我们就来判断一下当前的_memory是否还大于sizeof(T) , 如果大于 , 就继续走 ,如果不大于的话 , 那就重新申请 , 至于浪费的空间 , 那就浪费掉吧 , 而当我们的T是4个字节的时候(例如int) , 而在64位下 , 他的回收需要8个字节来存放指针 , 那这个时候_memory往后走4个字节一定是不够用的 , 这个时候我们得解决这个问题 , 确保_memory每一次向后走的空间能装下一个指针的大小

我们可以这样做

让当前T的大小与当前环境下的void*作比较 , 如果是小的话 ,就让他往前走一个指针大小的位置 , 否则就往前走T大小的位置

这还有个小东西需要解释一下 , 这个跟我们平时创建对象是有点不一样的 , 我们平时创建的对象系统是会自动调用默认构造和析构函数的 , 但是在这里的话 , 我们是在申请空间 , 系统是不会自动调用的 , 因此我们需要定位new(显示调用构造函数) , 和显示调用析构函数.

3.使用自由链表收集空间

上面已经把空间申请好了 , 然后需要被申请的空间已经由obj返回了 , 那么我们现在需要把自由链表部分的方法给写好

首先我们要明白 , 这个链表跟我们平时所使用的链表有什么不一样?

这个是我们平常使用的链表 , 这个链表前面存的是数据 , 后面的next指针存放的是下一个节点的地址

而自由链表虽然跟平时的链表操作是一样的 , 但是 , 他的节点并不是一个结构体 , 他的节点是每一个指针 , 那这样如何能存放下一个节点的地址呢?

做法就是把地址存放到这个指针的头4/8个字节 , 因为指针在32位的情况下 , 他是占用4个字节的 ,就需要4个字节的空间来存放 , 而如果在64位的情况下 , 他是占用8个字节的 , 这个时候就需要8个字节来存放

既然是要把这个玩意拆开4/8个字节 , 这个问题就有点难搞了 , 该怎么办呢?

其实可以使用*(void**)obj来进行拆解 , 这个就是把obj的前4/8个字节的空间给拆开了

当_freeList是空的时候 , 此时就可以直接把_freeList指向obj , 然后让obj的前4/8个字节指向空指针,

如果不为空 , 那么obj就先把当前_freeList所指向的空间存下来 , 然后再让_freeList指向obj , 在这里就相当于链表的头插.

obj插入之前 , _freeList指向的地方

obj插入之后的_freeList链表

4.自由链表返还空间

使用自由链表返还空间 , 在这里 , 就相当于单链表的头删 , 那么只需要创造一个指针获取到链表偶节点的下一个位置的地址 , 然后再让_freeList指向这里即可

既然是有了空间返还 , 那么我们在使用的时候 , 就会优先来对这块可以重复利用的空间加以利用 , 而不是用完了再继续开空间 , 所以我们可以把他放到New()里面 , 当作一个判断的条件

5.高并发内存池和new的测试

可以看到 , 这个new的效率是远远不如自己写的高并发内存池的(当然目前是在特定的情况下)

关键字:建网站需要多长时间_兰州网站分类导航_seo品牌优化百度资源网站推广关键词排名_自己开网店怎么运营

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: