美文网首页
堆内存申请与释放(简版)

堆内存申请与释放(简版)

作者: 111p1kk | 来源:发表于2019-06-11 21:36 被阅读0次

建议学习 Glibc内存管理 Ptmalloc2源代码分析(ps自行百度)
参考 蓝帽杯赛前直播 主播ppt 和 CTF-wiki

一. malloc

我们使用malloc时,函数真正调用的是__libc_malloc函数,该函数只是用来简单封装_int_malloc函数。注意:用户申请的字节一旦进入申请内存函数中就变成了无符号整数。

__libc_malloc

// wapper for int_malloc
void *__libc_malloc(size_t bytes) {
    mstate ar_ptr;
    void * victim;

首先检查是否有内存分配钩子,如果有,调用钩子并返回。

    void *(*hook)(size_t, const void *) = atomic_forced_read(__malloc_hook);
    if (__builtin_expect(hook != NULL, 0))
        return (*hook)(bytes, RETURN_ADDRESS(0));

寻找一个arena来试图分配内存。

    arena_get(ar_ptr, bytes);

调用_int_malloc函数去申请对应的内存。

    victim = _int_malloc(ar_ptr, bytes);

如果分配内存失败,ptmalloc会尝试再去寻找一个可用的arena,并分配内存。

    /* Retry with another arena only if we were able to find a usable arena
       before.  */
    if (!victim && ar_ptr != NULL) {
        LIBC_PROBE(memory_malloc_retry, 1, bytes);
        ar_ptr = arena_get_retry(ar_ptr, bytes);
        victim = _int_malloc(ar_ptr, bytes);
    }

如果申请到了arena,在退出前需要解锁。

    if (ar_ptr != NULL) __libc_lock_unlock(ar_ptr->mutex);

判断目前的状态是否满足以下条件
1.没有申请到内存 2.是mmap的内存 3.申请到的内存必须在其所分配的arena中

    assert(!victim || chunk_is_mmapped(mem2chunk(victim)) ||
           ar_ptr == arena_for_chunk(mem2chunk(victim)));

返回内存。
    return victim;
}

.............................................................................
此后省去源码分析...太繁琐,可以去wiki中查看
.............................................................................

_int_malloc

根据size

  • fastbin range:从fast bin中查找是否有合适的chunk
  • small bin range:先从small bin查找(small bin按照size排好,查找更快),再从unsorted bin查找
  • large bin range
    • 合并所有fastbin查找unsorted bin
    • large bin 中查找满足条件且最小的chunk,有则切分,剩余的放入unsorted bin //这是ptmalloc机制,他在分配large chunk时会先对堆中的碎片chunk进行合并,以便减少堆中的碎片
  • 最后从top chunk切割
  • 当topchunk也无法满足时,堆分配器进行mmap内存块申请

unsorted bin分配规则(大循环 - 遍历unsorted bin)

  • 尾部开始遍历
    • 如果chunk size够大,切分chunk,剩下的还在unsorted bin中
    • 如果不够大,将当前的chunk清出unsorted bin,并放入对应的bin中
  • 如果分配失败
    • 查找large bin
    • 扫描small bin / large bin查找

二. free

检测

  • 1.size是否属于fast bin
    • 是,插入fast bin
  • 2.是否是mmap分配
    • 是,释放mmap的chunk
  • 3.查看前一个chunk是否free
    • 是,合并
  • 4.查看下一个chunk是否为topchunk
    • 是,合并
  • 5.查看下一个chunk是否free
    • 是,合并
  • 6.放入unsorted bin

相关文章

  • 堆内存申请与释放(简版)

    建议学习 Glibc内存管理 Ptmalloc2源代码分析(ps自行百度)参考 蓝帽杯赛前直播 主播ppt 和 C...

  • JS的堆栈原理

    堆 指的是 堆内存, 堆是动态分配内存,内存大小不一,也不会自动释放。堆 是在程序运行时,而不是在程序编译时,申...

  • 内存四区模型

    操作系统把C代码分成四个区: (1)堆区(heap):一般由程序员分配释放(动态内存申请与释放),若程序员不释放,...

  • Linux系统内存管理与分页机制

    一、问题提出: 我们经常会使用malloc()以及free()函数进行堆区内存申请与释放。那么你是否会这样做: 我...

  • 十一、闭包(堆栈内存释放问题)------ 2020-04-05

    1、堆内存释放问题: 2、栈内存释放问题:

  • malloc,free底层实现

    设想:内存碎片:由于malloc在内存中连续sbrk申请内存,而释放内存只能从后往前释放。为了达到可以先释放前面申...

  • C++11(1)-智能指针

    C++裸指针的内存问题有:1、空悬指针/野指针2、重复释放3、内存泄漏4、不配对的申请与释放 使用智能指针可以有效...

  • 内存与性能

    申请与释放内存 申请内存的过程 用户态使用malloc向操作系统申请内存 操作系统查找页面是否有空闲内存,如果有则...

  • 【16】内存管理机制

    1. 内存:栈区间、堆区间 栈:栈上的内存是系统自动开辟,自动释放堆:堆上的内存需要手动开辟,手动释放。但在pyt...

  • js : 棧内存+堆内存+内存释放

    棧内存和堆内存 棧内存:提供了一个供JS代码执行的环境全局作用域私有所拥域 堆内存:存储引用数据类型的数据函数数据...

网友评论

      本文标题:堆内存申请与释放(简版)

      本文链接:https://www.haomeiwen.com/subject/bwntfctx.html