C++内存管理 第三讲 malloc_free

malloc/free

malloc的调用很快

一、VC6内存分配

heap想象为一堆内存

sbh_threshold 常量1016=1024-8(cookie) 为小区块服务SBH
代码执行次序是从下往上的
image-20220924170721397

新版本VC10,无论分配内存的大小,都给heapAlloc(操作系统,其实为小区块shb的动作都放到操作系统中做的),不再给SHB

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J92ojCbV-1664074458216)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924170934450.png)]

windows本身维护海量内存,你可以申请一块给你自己用

4096为初值,继续要的时候,4096会增长

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IE8KIPeF-1664074458217)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924171221208.png)]

BITVEC 32位的bit

bitvEntryHi+bitvEntryLo组合起来其实有64位 bit

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nJPDgqz2-1664074458218)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924171505441.png)]

内存分配的第一次

nSize=32*8=256 100h

**[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4fYUmO0I-1664074458219)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924172724614.png)]**

下面为调试器分配的空间,100h以外的都是给debug用的:

调整大小,就是真正分出去的大小(sizeof(_CtrMemBlockHeader)+100h+4(无人区,防止写出去(黑客啥的))),就是下图右边的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wkq7FA8T-1664074458221)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924172925696.png)]

头尾指针

memset :有些地方(无人区等等)会设初值,来检测变量是否改变

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXZdvp3B-1664074458223)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924173847541.png)]

前面的大小就为size(256),1016=1024-8(cookie)

让扩充的大小和阈值比较,如果小,就让sbh服务,否则让操作系统(HeapAlloc)服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NT9QOg8o-1664074458224)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924174125799.png)]

调整后的大小:加上cookie,调整为16的倍数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ClMF89Vv-1664074458226)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924174342225.png)]

131是130大小,1代表正在使用,还给shb时,置为130

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vOMXw75k-1664074458227)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924174715160.png)]

两个指针,一个指向真正的内存,一个指向管理中心(16K):

有32个group,

每个group有64对指针,用作双向链表

需要构建一个region控制台,仍未开始实际分配内存
region结构如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mzbfqMfd-1664074458228)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924175126036.png)]
struct tagEntry里面:
第一个表示指针借用前面的一部分而指向包括自己在内的三位【因为在后面控制8page时,需要设计成指向包括记录大小的头cookie和前后指针的三块内容;所以实际sizeFronnt=3,即从所指向的地址开始向下包括3块内容;另外因为设计成这样的功能,所以在GroupX中的64对某对链表指针没被投入使用时,一般都是往上指向前一个pEntryprev指针的地址从而向下包含3个的】。如下图所示。
第二个则表示类似链表的双向指针。

在这里插入图片描述

在这里插入图片描述

一个虚拟地址空间将被分32个小的虚拟地址空间,一个小的虚拟地址空间被分为8个page(4K)

在这里插入图片描述

上下设置-1(0xffffffff),未来合并内存的时候来区分不同的page

4080(4k=4096 - 黄色的,然后对16取整)是两个黄色之间的块

64个链表,分别负责 16 32 48 64 … 1024 的内存大小的分配 ,最后的1024的链表负责>=1k的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zaiYUGdT-1664074458231)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212733440.png)]

4080=ec0 真正要的是100h

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CEuSGA19-1664074458232)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212750649.png)]

MEM_RESERVE是让windows保留虚拟的空间地址,MEM_COMMIT是真正分配内存

32(个group)*64个bit,64个bit是来记录64个链表是否挂有内存,是的话,置位1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GqstoTaE-1664074458233)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212804393.png)]

240h本来要找第35个的链表,但是bit【35】位0,退而求其次,找36(也为0),找到最后的64.

cntEntries:要分配就要+1,收回来-1,为0的时候就收回来了,可以换给操作系统了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NNWBVZ08-1664074458235)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212815938.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BopH7SZj-1664074458236)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212827601.png)]

回收的时候借用嵌入式指针(用自身的一部分作为指针),指向35号链表,将bit[35]=1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LsB6L6Li-1664074458238)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212843960.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7o0zEx4p-1664074458238)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212853060.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A7bNBAYk-1664074458239)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212904870.png)]

有下cookie才能向上合并,不然找不到上一个空闲区得边界

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p8zqiL8H-1664074458241)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924212916541.png)]

为什么要分为32group(一个group串很多个链表也行)?因为分为32段每段切小,那样回收内存还给OS的概率会变大

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0YTpMlFJ-1664074458242)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924213845896.png)]

利用cntEntries判断时否全回收

cntEntries=0的时候,内存都还回来了,会是最开始的状态,因为散的内存最后都会被合并

不急着还给OS,因为下一次可能又向操作系统要,要有2个全回收再执行还

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oKaSm9GI-1664074458243)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220924214431060.png)]

defer延缓,手上永远保留一个全回收或者null

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DmMfalpC-1664074458244)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220925104314749.png)]

归还所有的内存,会恢复最开始的状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BKf0szYK-1664074458245)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220925104327509.png)]

调试下,追踪链表的函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CBZdVhsO-1664074458246)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220925104344518.png)]

GCC下的malloc也是这个行为,和上面讲的VC的malloc是一致的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g23o5G0O-1664074458248)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220925104356830.png)]

malloc很快,其实一直调用malloc也没问题,allocator相比于malloc减小cookie,而不是提升速度。

allocator比较霸道,还的内存会一直拿到手上

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eSUIUxgb-1664074458249)(C:\Users\13415\AppData\Roaming\Typora\typora-user-images\image-20220925104408163.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值