【C/C++】内存相关

avatar
作者
猴君
阅读量:0

内存相关

1 ptmalloc

ptmalloc是GNU C Library(glibc)中的默认内存分配器,广泛用于Linux系统。以下是对ptmalloc的详细解析:

一、概述

  • 起源:ptmalloc起源于Doug Lea的malloc实现,并由Wolfram Gloger进行改进,以支持多线程。
  • 目标:ptmalloc的主要目标是为多线程应用程序提供高效的内存分配和释放。
  • 名称含义:“pt”代表“pthreads”,指的是POSIX线程库,表明其支持多线程的特性。

二、特点

  1. 多线程支持:ptmalloc通过为每个线程提供本地缓存(称为线程缓存或tcache)来减少线程之间的竞争,提高内存分配的速度。
  2. 内存分割:将内存分为小块(small bins)和大块(large bins),以便更有效地管理不同大小的内存请求。
  3. 动态分配区:ptmalloc引入了动态分配区(dynamic arena)的概念,与主分配区(main arena)一起通过环形链表进行管理。每个分配区利用互斥锁实现线程对该分配区的访问互斥。
  4. 内存管理策略:预先向操作系统申请并持有一块内存供用户malloc,同时管理已使用和空闲的内存。用户执行free时,会将回收的内存管理起来,并通过策略决定是否交还给操作系统。

三、数据结构

ptmalloc中主要的数据结构包括:

  • malloc_state(Arena header):描述了一个分配区的状态,包括bins、top chunk、last remainder chunk等信息。
  • heap_info(Heap Header):每个堆都有自己的堆Header,用于管理堆的信息。
  • malloc_chunk:是内存块(chunk)的基本组织单元,用于描述每个内存块的状态和大小。每个chunk都有自己的header,包括prev_size(前一个chunk的大小,如果前一个chunk是空闲的)、size(当前chunk的大小,包括开销)、以及用于链表管理的指针(fd、bk等)。

四、内存分配与释放

  1. 内存分配

    • 线程首先尝试从自己的线程缓存中满足内存请求。
    • 如果线程缓存无法满足,则尝试从全局的bins中查找合适的内存块。
    • 如果bins中也找不到合适的内存块,则考虑从top chunk中分配或扩展top chunk。
    • 对于大块内存请求,可能会直接使用mmap()从操作系统申请内存。
  2. 内存释放

    • 释放的内存块首先被加入到unsorted bin中。
    • 根据内存块的大小,可能会被合并到small bins、large bins或fast bins中。
    • 如果内存块足够大或空闲时间过长,可能会被交还给操作系统。

五、优缺点

  • 优点

    • 成熟稳定,与GNU C库紧密集成。
    • 支持多线程,通过线程缓存减少锁竞争。
    • 通过bins和top chunk等机制提高内存分配和释放的效率。
  • 缺点

    • 在高并发场景下,仍然可能存在锁竞争问题。
    • 与其他先进的内存分配器(如tcmalloc、jemalloc)相比,性能可能不是最优的。

六、总结

ptmalloc作为glibc中的默认内存分配器,在Linux系统中扮演着重要角色。它通过一系列机制来提高内存分配和释放的效率,并支持多线程应用程序。然而,随着技术的发展和应用场景的变化,ptmalloc也需要不断优化和改进以适应新的需求。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!