【问题标题】:What are the advantages and disadvantage of using jemalloc vs malloc vs calloc and other common alternatives?使用 jemalloc、malloc、calloc 和其他常见替代方法的优缺点是什么?
【发布时间】:2018-02-25 09:19:28
【问题描述】:
今天阅读Rust subreddit,我遇到了cmets:
jemalloc 针对(多线程)速度而非内存使用进行了优化
在做了更多研究后,我发现还有更多的替代品(例如 calloc)。
我想了解不同内存分配器的优缺点是什么?
如果这个问题看起来很傻,我的背景主要是解释性语言(它不会暴露如此细粒度的内存控制)。
【问题讨论】:
标签:
malloc
dynamic-memory-allocation
realloc
calloc
jemalloc
【解决方案1】:
malloc、calloc 和 realloc
这些函数不是不同的分配器。它们是从同一个分配器请求内存的不同方式。
malloc 提供内存而不对其进行初始化(填充之前用户存储在其中的任何内容)。
calloc 与malloc 相同,但它也会初始化内存(用零字节0x00 填充它)。
realloc 获取已分配的内存并允许用户调整其大小。
因此,在分配器及其不同实现的上下文中,malloc、calloc 和 realloc 并未独立列出,因为每个分配器实现都需要自己的这些函数版本。
jemalloc, ptmalloc, ...
当有人想要实现不同的分配器时,他不能(可以但不应该默认)将其命名为malloc,因为它会与 C 标准库之一发生冲突。相反,他们通常给它一个不同的前缀,如jemalloc、ptmalloc、nedmalloc、tcmalloc 和 others。
值得一提的是,C 标准库本身也有多个实现,每个实现其分配器的方式都不同。所以malloc 将根据编译代码时使用的标准库有不同的实现。例如:GNU C 标准库、MSVC 标准库等。
不同的分配器有什么区别?
要了解每种实现的确切优缺点,必须阅读每个实现的作者/作者编写的文档(如果存在),阅读代码以了解算法或阅读专家撰写的文章/研究论文关于那个特定的实现。
但是,如果我要对这些实现之间的差异进行分类,我会列出以下内容:
- 一些实现侧重于某些使用模式,并尝试对其进行优化,即使以降低其他情况的效率为代价。这方面的一个例子是
jemalloc,他们专注于优化来自多个线程的分配以使其更快,但以使用更多内存为代价。这些类型的分配器通常是在对特定案例进行仔细调查后部署的,该案例表明它将从这种权衡中受益。
- 一些实现对分配器的使用设置了一定的限制,以使其更快。一个例子是单线程分配器,它将消除对同步对象的需求以使其更快。
- 其他实现尽量通用,不偏向于其他任何情况。此类别包括标准库中包含的默认分配器。