理解jemalloc内存分配原理(jemalloc内存分配器详解)

一、jemalloc是什么?

jemalloc是一个高效的、可伸缩的内存分配器,最初由Jason Evans创造于2005年。相比于系统自带的malloc,jemalloc性能更优、效率更高、可扩展性更好。它被广泛应用于很多项目中,比如对内存使用要求非常高的数据库系统mongodb。此外,为了适应不同的应用场景,jemalloc提供了非常灵活的配置参数,并且其代码开放、易于二次开发。

二、jemalloc内存分配原理

jemalloc的内存分配算法是基于二叉堆实现的。在jemalloc的实现中,二叉堆被用来维护一系列的链表,在这些链表上的内存块都是同一大小的。所有的链表都有一个指针,指向下一个更大的链表,即更大的内存块尺寸,这些链表上的内存块大小以2为底,随着链表的指针指向更大的内存块尺寸而增大。

当应用程序请求分配内存时,jemalloc会使用一个“slab”的概念来表示一系列内存块。slab的大小是特定的,通常是16KB或32KB。分配器在从jemalloc中获取未使用的内存之前会首先写入slab的头部,确保客户端代码不能篡改该内存。然后,jemalloc将slab添加到特定的链表以供下次使用。

同时,分配器会维护另一系列的链表,称为“微型”链表。这些链表上的内存块大小以8为底,jemalloc会尝试在其中一找到可以将内存分配给应用程序的内存块。如果没有找到,则jemalloc会在链表上对更大的内存块做类似的操作,最终找到一个足够大的内存块并尝试将其拆分为两个相等大小的内存块。一个内存块被分配给应用程序,另一个内存块被放回到jemalloc中的合适的链表中。

三、jemalloc的高效性能

jemalloc堆内作业的几个优点:

1、jemalloc极大程度地减少了锁竞争的概率。jemalloc运行时数据结构的组织方式使得所有线程访问jemalloc堆时不太可能出现锁竞争,这种设计能够极大程度上提高jemalloc分配器的吞吐量。

2、jemalloc内部使用的算法随机服务于所有的客户端,这就使得任意给定分配模式的应用程序无法控制jemalloc的数据结构,这种随机性可以增加攻击者的难度。

3、有一些友好的特性。例如,在jemalloc中,对于特定大小的内存块,内存管理器可以通过折半二叉平衡树快速定位其相应的slab,而不必先扫描整个链表。此外,jemalloc中各个链表的大小是以2为底对数递增的,由此可以实现更加高效的内存分配。

四、jemalloc的使用

#include 
#include 

int main() {
    // 设置jemalloc的初始化初始化配置
    je_mallctl("config.dss", NULL, NULL, "arenas:8,dss:back");
    je_mallctl("config.prof", NULL, NULL, "prof:true,prof_active:true");

    size_t s = 10 * 1024 * 1024;
    // 分配10MB的内存
    void* p = je_malloc(s);
    printf("p=%pn", p);

    // 释放内存
    je_free(p);
    return 0;
}

五、jemalloc的配置

jemalloc的分配器可以通过大量的调整来提高吞吐量、性能和可伸缩性。以下是jemalloc的一些主要配置设置:

1、arena:这是jmalloc堆中的一块内存池。可以使用更多的内存池(称为“arene”)来减少锁竞争,从而实现性能和扩展性的提高。默认情况下,arena的数量为1,除了高端分配外,所有内存请求都将从这一内存池中分配。

2、dss:jemalloc通过从堆的分配区间内分配线性内存来分配内存。对于小于128KB的内存分配,jemalloc会从内部slab分配器中分配内存。使用dss选项来指定jemalloc如何维护在该区间内分配的线性内存。默认情况下,dss是none,此时默认使用了内存映射文件。

3、opt:在jemalloc的config数组中定义了几个性能优化选项。选项名称是用字符串而不是预处理程序符号定义的。默认情况下,所有的优化选项均为禁用状态。不过,一些复杂的应用程序可能会受益于启用某些选项,例如thread.arena_max。

4、prof:jemalloc的性能分析器是prof(采样分析器)。其中,prof:true启用性能分析器,该分析器分析jemalloc在运行时的行为。这些数据可用于分析jemalloc的性能瓶颈、调整jemalloc的内部变量、以及在实际问题上进行检查。另外,要想提交perf.centers服务,需要将node.fcntl路径设置为有效的perf.centers路径。

六、jemalloc的优缺点

jemalloc的优点:

1、jemalloc的架构是面向线程设计的,因此能够大大减少锁竞争。与glibc的PT(进程范围内锁)不同,jemalloc使用的是MT(线程范围内锁)。

2、jemalloc的设计是模块化的。它提供了许多控制jemalloc的配置参数,使其可以吸纳不同的应用程序,并且这些参数可以在用户空间中进行动态调整。

3、jemalloc包含一套非常好的调试工具和分析工具,可以帮助应用开发者更好地理解jemalloc内部的工作机制。

jemalloc的缺点:

1、jemalloc对某些应用程序的性能有着不利影响,例如拥有大量短暂生存周期对象的应用程序。

2、jemalloc还与本地缓存有一些问题。例如Kcache大小不足的情况下,可能会导致jemalloc分配器变慢。

3、jemalloc并不是任意情况下都能表现优异。在特定的工作负载下,例如存在大量小对象的工作负载,jemalloc的表现可能不如其他的编译器。

七、jemalloc的开源精神

jemalloc由Jason Evans编写,是一个开源项目,任何人都可以在GitHub上看到它的代码,甚至自己编写版本以解决针对特定应用程序的问题。

在这个开源精神中,数据结构不仅仅是理论上的实践工具,也是一种充分利用计算机强大计算能力的方法。jemalloc与众多开源项目一起,展示了Linux 系统中的技术与创造力。对于任何想要深入了解jemalloc和其他内存分配器的人来说,希望本文能为其提供指引和帮助。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平