Mimalloc
这篇文章中我们会介绍一下mimalloc的实现。首先我们需要了解的是其整体结构,mimalloc的结构如下图所示
mimalloc整体结构
mimalloc是微软最近开源的一个malloc实现,其实验数据表明相比于jemalloc、tcmalloc等实现大约快了10%。其通过将空闲块列表(Free List)进行分片(Sharding)来获取更好的分配的内存的局部性,从而提升性能。在mimalloc中一共进行了4次Free List的Sharding。接下来我们会分别介绍这4个Free List的Sharding的位置以及其为什么要进行Free List的Sharding。
在其他的内存分配器的实现中,一般会为每一类大小的对象保留一个Free List,随着内存的不断分配与释放,这个列表中的对象可能散布在整个地址空间中,因此内存分配的局部性较差。而在mimalloc中,其通过将内存分页,每个页负责一个特定大小的内存的分配,每个页有一个Free List,因此内存分配的空间局部性较好。
Google File System是谷歌开发的分布式文件系统,GFS虽然也像之前的分布式文件系统一样希望能够达到较好的性能、扩展性、可靠性、可用性,但是其设计主要是从各种使用GFS的应用的工作负载以及环境来出发的。设计GFS时,开发者对GFS的实际使用环境做出了一系列的假设,包括:
对网络层次的划分有多种,例如OSI的七层网络模型,TCP/IP的四层网络模型以及部分书籍中的五层网络模型。我们接下来分别介绍这几种网络模型,看看每层的功能,之后会分别对每层进行更详细的介绍。
五层网络模型中,网络由下至上分别为物理层、数据链路层、网络层、传输层、应用层。其每层的功能如下:
操作系统需要为底层的硬件资源提供一种抽象,从而向上层隐藏底层实现细节,并便于上层软件的开发。
而对存储器的最简单的抽象就是不进行抽象,每个程序可以直接访问内存,不同进程由于使用的是同一个地址空间,因此可以访问和修改其他进程甚至操作系统的数据。在这种抽象的情况下,如果需要运行多个进程可以利用交换技术,每次需要运行其他进程时会先将当前进程的数据保存到磁盘,然后调入其他进程;或者可以将地址空间进行划分,每个进程使用不同的地址空间来支持多个进程的运行。
由于直接使用物理内存空间作为存储器抽象没有为上层软件开发提供一个足够好的环境,因此人们开始将物理内存抽象为地址空间。由于地址空间是每个内存可用于寻址的一系列地址的集合,因此需要将为每个进程划分一个自己的地址空间,一个方法是使用基址寄存器和界限寄存器,其中基址寄存器用于保存该进程地址空间的0地址在物理地址空间的位置,而界限寄存器用于保留程序的长度。因此程序需要装载到内存中连续的地址中,而每次进程访问内存、取指或者读写数据时CPU会在将地址发送到内存的总线前加上基址,同时监测偏移是否超过了界限寄存器。使用基址寄存器和界限寄存器可以非常方便的为每个进程提供私有的地址空间,但是由于每次访问内存都需要进行加法和比较运算因此会带来一定的额外负担,而且要求每次将程序装载到连续的内存空间中。