阅读量:0
内存相关
1 ptmalloc
ptmalloc是GNU C Library(glibc)中的默认内存分配器,广泛用于Linux系统。以下是对ptmalloc的详细解析:
一、概述
- 起源:ptmalloc起源于Doug Lea的malloc实现,并由Wolfram Gloger进行改进,以支持多线程。
- 目标:ptmalloc的主要目标是为多线程应用程序提供高效的内存分配和释放。
- 名称含义:“pt”代表“pthreads”,指的是POSIX线程库,表明其支持多线程的特性。
二、特点
- 多线程支持:ptmalloc通过为每个线程提供本地缓存(称为线程缓存或tcache)来减少线程之间的竞争,提高内存分配的速度。
- 内存分割:将内存分为小块(small bins)和大块(large bins),以便更有效地管理不同大小的内存请求。
- 动态分配区:ptmalloc引入了动态分配区(dynamic arena)的概念,与主分配区(main arena)一起通过环形链表进行管理。每个分配区利用互斥锁实现线程对该分配区的访问互斥。
- 内存管理策略:预先向操作系统申请并持有一块内存供用户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等)。
四、内存分配与释放
内存分配:
- 线程首先尝试从自己的线程缓存中满足内存请求。
- 如果线程缓存无法满足,则尝试从全局的bins中查找合适的内存块。
- 如果bins中也找不到合适的内存块,则考虑从top chunk中分配或扩展top chunk。
- 对于大块内存请求,可能会直接使用mmap()从操作系统申请内存。
内存释放:
- 释放的内存块首先被加入到unsorted bin中。
- 根据内存块的大小,可能会被合并到small bins、large bins或fast bins中。
- 如果内存块足够大或空闲时间过长,可能会被交还给操作系统。
五、优缺点
优点:
- 成熟稳定,与GNU C库紧密集成。
- 支持多线程,通过线程缓存减少锁竞争。
- 通过bins和top chunk等机制提高内存分配和释放的效率。
缺点:
- 在高并发场景下,仍然可能存在锁竞争问题。
- 与其他先进的内存分配器(如tcmalloc、jemalloc)相比,性能可能不是最优的。
六、总结
ptmalloc作为glibc中的默认内存分配器,在Linux系统中扮演着重要角色。它通过一系列机制来提高内存分配和释放的效率,并支持多线程应用程序。然而,随着技术的发展和应用场景的变化,ptmalloc也需要不断优化和改进以适应新的需求。