usdt自动充值(www.payusdt.vip):macos 内存分配学习条记

admin 4个月前 (03-30) 科技 55 0

USDT自动充值API接口

菜宝钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

学习的 ppt

谢谢 AngelBoy1

地址

基础

在macOS中行使的是 libcmalloc

在这个模式中 堆块对应为 tiny *** all large

  • tiny (Q = 16) ( tiny < 1009B )
  • *** all (Q = 512) ( 1008B < *** all < 127KB )
  • large ( 127KB < large )

每个magazine有个cache区域可以用来快速分配释放堆。

quantum

tiny

可以称为 block

Tiny 内存堆块中,最小的单元为quantum` 巨细0x10 字节。

纪录堆块巨细的信息为 以quantum 为单元的 msize

我们malloc 分配的 chunk 由许多的 block 组成

没有 被分配使用的 block 内里是没有元数据 (metadata)的

*** all

*** all 中 这 block 在 region 中的 巨细为 0x200

也被成为 quantum

没有 被分配使用的 block 内里是没有元数据 (metadata)的

结构剖析

每个历程包罗3个区域,划分为tiny rack, *** all rack, large allocations

每个区域内里包罗了 多个 magazine区域 是流动可变的。

magazine区域 中又有多个 Region 对于 tiny rack 1MB 和 *** all rack 8MB他们的巨细差异

“Region”中包罗三样器械,一个是以Q为单元的内存block, 另有个是认真将各个”Region”关联起来的trailer另外一个就是纪录chunk信息的metadata

源码中对应的结构

tiny Region {
    Q(1Q = 16) * 64520
    region_trailer_t trailer
    metadata[64520/sizeof(uint32_t)] {
        bitmaps[0]: uint32_t header = 形貌哪个block是起始chunk
        bitmaps[1]: uint32_t inuse = 形貌chunk状态(busy/free)
    }   
}

Small Region {
    Q(1Q = 512) * 16320
    region_trailer_t trailer
    metadata[16320] {
        bitmaps[0]: uint16_t msize = 最高一位形貌chunk状态(busy/free), 其余位形貌chunk的Q值Q值代表与下一个chunk相差若干个Q
    }
}

tiny

Tiny 对照类似于 linux 下的堆块

tiny chunk

Free 后会被放在对应的 freelist 上

当 tiny 堆块被 free 后会在堆块内写入数据

由于申请的 chunk 是 0x10 巨细的单元 ,以是 末尾都是 0 右移不会影响恢复。

最高以为 0-0xf 内里随便值

checksum(prev_pointer), checksum(next_pointer), msize

这里虽然和 linux 一样保留在 freelist 然则free 后的 chunk 中保留的却不是 原始的 上一个或者下一个chunk的地址 而是经由 checksum 盘算的 chunk地址。

算法为

Checksum = SumofEverybytes(ptr^cookie)&0xf

会随机天生一个cookie,这个cookie会pointer举行下面的盘算天生一个checksum, 然后将(checksum << 56 ) | (pointer >> 4)运算后将checksum保留在高位上,以便检测堆的元数据是否被溢出损坏

保留的指针的结构

在 free 后的chunk结构中

Msize 纪录的是 block 的个数,好比这个 chunk 巨细为 0x40 那么他对应 4个 block 以是 Msize 的值为 4

tiny magazine

结构

这里的 map_last 类似于一个缓存,对于free 的chunk(<=0x100) 不会直接返回给盘算机,而是先保留在 这个地方,当下次申请的试试优先使用他,在free 下一个 chunk 之后才会将 第一个free 的chunk 真正的free掉。

map_last_free 保留的是 最后一次free 的chunk

map_last_free_msize 保留的是 最后一次free 的chunk的巨细

map_last_free_rgn 保留的是 最后一次free 的chunk region

然后下面的 的才是 我们的 free_list

每个巨细为 0x10 一共有 64 个 free_list

保留在 free_list 上面类似 linux下的 *** allbins 保留方式

tiny Region

tiny Region {
    Q(1Q = 16) * 64520
    region_trailer_t trailer
    metadata[64520/sizeof(uint32_t)] {
        bitmaps[0]: uint32_t header = 形貌哪个block是起始chunk
        bitmaps[1]: uint32_t inuse = 形貌chunk状态(busy/free)
    }   
}

tiny 的 Region 结构图

tiny_header_inuse_pair_t 为8字节 也就是 这个 Region 末尾的 元数据 (matedata)

前4字节 为 Header 用于指示对应的块是不是 chunk 头

后4字节 为 inuse 用于纪录这个chunk 是否被使用

分配机制

分配 tiny 的巨细为 <1008 bytes

当我们申请时,会先去检测

  1. tiny magazinetiny_mag_ptr->mag_last_free_msize == msize 是否上一个 free 的chunk 巨细和我们现在要申请的chunk 巨细一样,这个 tiny magazine 中的 chunk 类似存储在 缓存中 cache

  2. 若是 tiny magazine 中的 mag_last_free_msize 不相符我们需要的,会去 free_list 中找到对应的chunk,然后会 这个 选择的这个 chunk->next 指针举行解密。

  3. 若是 也没用对应巨细的 chunk,回去 free_list 中存在 chunk 且 巨细能够使用的 list 中取出chunk 将chunk 举行切割,取出,然后将剩下的chunk 放入对应 巨细的 free_list

  4. 若是 free_list 中没有对应的 free 的chunk 能被申请,且 tiny region end 巨细知足 申请的chunk巨细 那么就会从 tiny region end 中申请
  5. 当找到对应巨细的 chunk 后,会跟新 metadata(tiny Region 中的 tiny_header_inuse_pair 修改标志位 标明chunk 的使用情形) 然后将申请的 chunk 返回给 用户 。

接着会行使 szone_size 巨细索引方式,验证 头和使用状态。

Free机制

  1. 若是free 的chunk 的 mszie < 0x10,当前堆块会与 cache (缓存内里的) 的freeed 堆块交流。

  2. tiny_free_no_lock 类似于 glibc 的堆块合并操作, 合并上一个 和 下一个 freed chunk 然后祛除对应的 inuse 位

    • 行使 上一个 freed chunk 末尾的 mszie 来找到上一个 freed chunk 的位置

      ,

      usdt收款平台

      菜宝钱包(www.caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

      ,
    • 行使 当前chunk 的 mszie 和当前chunk 的最先位置盘算 下一个 freed chunk 的位置

    • 在合并之前会举行 unlink 操作。

ulink

unlink 操作的时刻 类似 glibc 然则他是先对 chunk 内里的指针举行 unchecksum 限制也是和 glibc 一样的

ppt 图片注释

首先 我们的 free_list 内里已经存在一个 free了的 chunk 且 我们的 Cache 内里的内容为空

这个时刻我们 free(P) 我们的 P 会被放入到 Cache 内里且纪录当前 free 的 P 的size 和 来自的 Region


接着 我们在 free(Q) 这个时刻由于 P 是在 Cache 内里的,这个时刻 Q 被free 了,我们的 Cache 内里的 P 会被放置到 对应的 free_list,这个时刻这个 free_list 中已经存在一个 free 了的 chunk。

我们要放入 P 入这个 free_list 首先会 检测 free_list 内里的chunk 的 prev header 和 inuse 的元数据位

然后回去 清空 tiny_list 内里 元数据的 P 的 header 和 inuse 位。

然后对 P 和 free_list 内里的chunk 举行unlink 操作,由于是 相邻的,于是举行合并。然后再去检查下一个 chunk举行上面操作。

接着 合并的chunk 会被放到 对应巨细的 free_list 内里

Small

*** all chunk

*** all chunk

结构类似月 tiny chunk 纷歧样的是这里 pre 和 next 指针用的是原始指针

不用的是 pre 和 next 指针不是相邻的 而是 在 pre next 之后 添加一个 字节来储存 checksum 的值

且这个值会被填充为 8 字节

obb free chunk

且另有一种称为 oob free chunk 的 用于实现页面临其。这样的 chunk 中没有 元数据(metadata)

oob_free_entry_s 行使来治理 oob chunk。


Prev 和 next 指向表中同样巨细的 free 的chunk

保留的是 原始数据。

Ptr 是对这个 oob chunk 的标志,oob chunk在 region 内里的索引 和 是否这个 oob 被free(最高位标志)

*** all magzine

前面的基础 和 tiny magazine 一样的

前面的 map_last_xxx 保留上次 free 后放入到 这里的 chunk 也就是 一个 Cache 缓存

这里是 free_list 是以 0x200 字节为单元 保留的值 oob_free_entry 然后凭证 oob_free_entry 的 Ptr 指针找到对应的 free 的chunk 的位置。oob_free_entry 又保留在 *** all Region 的末尾

其中 free_lits 内里存储的 chunk 不会 直指向 magzine

*** all Region

其中保留 chunk *** all_region_end *** all_meta_words *** al_oob_free_entries

block 巨细为 0x200

这个 region

​ 巨细默以为 0x800000

​ block 的个数为 16319

region 末尾存在 *** all_meta_words *** all_oob_free_entries

*** all_meta_words

内里保留的元素对应 region 内里的 每个 block

且内里 保留了 chunk 的巨细和 inuse 位

这内里保留的 block 会保留当前使用中的 chunk 的 size 巨细

​ 也会保留 freed chunk 的 巨细和 flag 标志

这个 block 内存的最高一位 标志chunk 是否被使用

*** all_oob_free_entries

一共 32 个保留位置

保留 oob_free_entry (实现页面临齐)

free 后结构

分配机制

分配巨细 为 1008 - 128kb 行使 *** all_malloc

  1. 和 tiny 一样 先去查看 magzine 内里 map_last_xxx (Cache) 是否保留了 对应 msize 的free 的 *** all chunk。若是存在直接取出 Cache 内里值保留一个上一次 free 的 chunk

  2. 若是没有合适的,会去对应的 free_list 内里找。
    一样平常情形下的 chunk 会执行 unchecksum next 指正。

    接着会去检测 双链接表 执行unlink 操作, 判断 next->prev == ptr

    和 tiny chunk 的申请是一样的,然则 oob chunk 内里ptr 地址存的是 原始数据 不用挪用 unchecksum

  3. 且是从 free_list 头取出

  4. 申请获得 chunk 后 会修改 *** all Region 末尾的 *** all_oob_free_entries 内里临应的标志 修改 flag|size 为 mszie msize 的巨细为 0x600/0x200 这样的盘算

Free机制

  1. 把 chunk 放入 Cache

  2. 在free *** all chunk 中也会存在 合并操作。

    • 首先凭证这个堆块 prev 指针找到上一个堆块,凭证堆块所在的 Region 末尾的 *** all_meta_words 去查看这个 上一个堆块 标志位,判断这个堆块 是否被free 和 他的msize。从而定位到 上一个chunk 的位置。

    • 然后找到 下一个堆块的 判断是否 free 获得他的巨细

    • 接着 合并相邻地址的 prev next free 的chunk (先举行unlink 然后举行 合并

unlink

首先凭证 是否为 oob chunk

若是为 oob chunk 直接获取 对应的 ptr 指正,若是不是先举行 unchecksum 然后举行合并

也是和 tiny chunk 一样会验证 chunk 的 prev->next == next->prev == ptr

确立才回挪用 unlink

图解

和tiny 一样


Sunbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:usdt自动充值(www.payusdt.vip):macos 内存分配学习条记

网友评论

  • (*)

最新评论

标签列表

    文章归档

      站点信息

      • 文章总数:1678
      • 页面总数:0
      • 分类总数:8
      • 标签总数:1763
      • 评论总数:1413
      • 浏览总数:176552