内存池
应用层内存池 -> C 库内存池
Google 的 TCMalloc(预分配内存更少的内存池) 和 FaceBook 的 JEMalloc
Linux 系统的默认 C 库内存池 Ptmalloc2
当主进程下申请 1 字节的内存时,Ptmalloc2 会预分配 132K 字节的内存(Ptmalloc2 中叫 Main Arena),应用代码再申请内存时,会从这已经申请到的 132KB 中继续分配,当我们释放这 1 字节时,Ptmalloc2 也不会把内存归还给操作系统
多线程每个子线程预分配的内存是 64MB,子线程内存池最多只能到 8 倍的 CPU 核数(通过设置 MALLOC_ARENA_MAX 环境变量,可以限制线程内存池的最大数量)
TCMalloc 适用的场景,它对多线程下小内存的分配特别友好,当应用场景涉及大量的并发线程时,换成 TCMalloc 库也更有优势
每次分配内存,Ptmalloc2 一定要加锁,才能解决共享资源的互斥问题。然而,加锁的消耗并不小。如果你监控分配速度的话,会发现单线程服务调整为 100 个线程,Ptmalloc2 申请内存的速度会变慢 10 倍。TCMalloc 针对小内存做了很多优化,每个线程独立分配内存,无须加锁,所以速度更快
如果主要分配 256KB 以下的内存,特别是在多线程环境下,应当选择 TCMalloc;否则应使用 Ptmalloc2,它的通用性更好。
由于每个线程都有独立的栈,所以分配内存时不需要加锁保护,而且栈上对象的尺寸在编译阶段就已经写入可执行文件了,执行效率更高,缺点是生命周期和栈空间限制
Ptmalloc2 为子线程预分配了 64MB 内存池,虽然增大了内存消耗,但却加快了分配速度,这就是以空间换时间的思想