文章目录
这个项目做的是什么?
当前项目是实现一个高并发的内存池 ,他的原型是google的一个开源项目 tcmalloc
,tcmalloc全称Thread-Caching Malloc
,即线程缓存的malloc ,实现了高效的多线程内存管理 ,用于替代系统的内存分配相关的函数(malloc、free)。
我们这个项目是把tcmalloc最核心的框架简化后拿出来,模拟实现出一个自己的高并发内存池,目的就是学习tcamlloc的精华,这种方式有点类似我们之前学习STL容器的方式。但是相比STL容器部分,tcmalloc的代码量和复杂度上升了很多,大家要有心理准备。当然从另一方面来看,难度的上升,我们的收获和成长也是在这个过程中同步上升。
另一方面tcmalloc是全球大厂google开源的 ,可以认为当时顶尖的C++高手写出来的,他的知名度也是非常高的,不少公司都在用它,Go语言直接用它做了自己内存分配器。所以很多程序员是熟悉这个项目的,那么有好处,也有坏处。好处 就是把这个项目理解扎实了,会很受面试官的认可。坏处就是面试官可能也比较熟悉项目,对项目会问得比较深,比较细。如果对项目掌握得不扎实,那么就容易碰钉子。
这个项目的要求的知识储备和难度?
这个项目会用到 C/C++、数据结构(链表、哈希桶)、操作系统内存管理、单例模式、多线程、互斥锁等等方面的知识
。
什么是内存池
池化技术
所谓"池化技术",就是程序先向系统申请过量的资源,然后自己管理,以备不时之需。
之所以要申请过量的资源,是因为每次申请该资源都有较大的开销 ,不如提前申请好了,这样使用时就会变得非常快捷,大大提高程序运行效率
。
在计算机中,有很多使用"池"这种技术的地方,如:内存池,还有连接池、线程池、对象池等。以服务器上的线程池为例,它的主要思想是:先启动若干数量的线程,让它们处于睡眠状态,当接收到客户端的请求时,唤醒池中某个睡眠的线程,让它来处理客户端的请求,当处理完这个请求,线程又进入睡眠状态。
内存池
内存池是指程序预先从操作系统申请一块足够大内存 ,此后当程序中需要申请内存的时候,不是直接向操作系统申请,而是直接从内存池中获取 ;同理当程序释放内存的时候,并不真正将内存返回给操作系统,而是返回内存池 。当程序退出(或者特定时间)时,内存池才将之前申请的内存真正释放。
内存池主要解决的问题
内存池主要解决的当然是效率的问题,其次如果作为系统的内存分配器的角度
,还需要解决一下内存碎片的问题 。
那么什么是内存碎片呢?
再需要补充说明的是:
内存碎片分为外碎片和内碎片
,上面我们讲的外碎片问题。
外部碎片:是一些空闲的连续内存区域太小,这些内存空间不连续,以至于合计的内存足够,但是不能满足一些的内存分配申请需求。
内部碎片:是由于一些对齐的需求,导致分配出去的空间中一些内存无法被利用。内碎片问题,我们后面项目就会看到,那会再进行更准确的理解。
malloc
C/C++中我们要动态申请内存都是通过malloc去申请内存 。
但是我们要知道,实际我们不是直接去堆获取内存的,而malloc就是一个内存池。
malloc() 相当于向操作系统"批发"了一块较大的内存空间,然后"零售"给程序用。当全部"售完"或程序有大量的内存需求时,再根据实际需求向操作系统"进货"。
malloc的实现方式有很多种,一般不同编译器平台用的都是不同的。比如windows的vs系列用的微软自己写的一套,linux gcc用的glibc中的ptmalloc。