malloc 内存分配
1. linux内存布局
最上层是内核空间,然后是栈空间,再然后内存映射区域,然后堆区域,最后是静态区域
2. 在Linux下分配堆内存需要使用brk系统调用,而这个系统调用只是简单地改变堆顶指针而已,也就是将堆扩大或者缩小。所以如果我们遇到这种情况,是没有办法直接将内存归还给操作系统的
3. 如果归还memory2的内存的时候,把memory1的内存也给归还了。
可以先把memory2的内存缓存起来,等用了,再给程序,不用先归还给系统。
但用容易产生内存碎片
4. tcmalloc就是一个内存分配器,管理堆内存,主要影响malloc和free,用于降低频繁分配、释放内存造成的性能损耗,并且有效地控制内存碎片
tcmalloc区别地对待大、小对象。它为每个线程分配了一个线程局部的cache,线程需要的小对象都是在其cache中分配的,由于是thread local的,所以基本上是无锁操作(在cache不够,需要增加内存时,会加锁)
同时,tcmalloc维护了进程级别的cache,所有的大对象都在这个cache中分配,由于多个线程的大对象的分配都从这个cache进行,所以必须加锁访问,细粒度、高效的自旋锁(Spinlock)
5. tcmalloc中,小于等于32 KB的对象被称为小对象,大于32 KB的是大对象。在小对象中,小于等于1024 B的对象以8n B分配,大于1025 B,小于等于32 KB的对象以128n B大小分配,例如,要分配20 B则返回的空闲块大小是24 B,小于等于B的,这样在小于等于1024 B的情况下最多浪费7 B,大于1025 B则浪费127 B。而大对象是以页大小4 KB进行对齐的,最多会浪费4KB-1 B
6. 内存池的另一个好处是我们可以为每个线程单独分配一个内存池,而不需要整个进程共用,这样在多线程的程序中,还可以避免多个线程之间同时分配内存时频繁上锁
当我们发现由于小块内存过多而引发内存碎片时,只需要将数据内存中的内存进行压缩(也就是将正在使用的内存重新排布到一起,将空闲的内存空间预留出来,可以看成内存的碎片整理),并修改句柄列表中句柄指向的实际地址,这样就可以一定程度上解决内存碎片问题