memory-management - 为什么 Redis 内存碎片小于 1

标签 memory-management redis glibc

Redis 支持 3 种内存分配器:libc、jemalloc、tcmalloc。当我进行内存使用测试时,我发现 INFO MEMORY 中的 mem_fragmentation_ratio 对于 libc 分配器可能小于 1。对于 jemalloc 或 tcmalloc,这个值应该大于或等于 1。

谁能解释为什么 libc 的 mem_fragmentation_ratio 小于 1?

Redis 版本:2.6.12。中央操作系统 6

更新:

我忘了提到一个可能的原因是交换发生并且 mem_fragmentation_ratio 将 < 1。

但是当我进行测试时,我会调整 swapiness,甚至关闭 swap。结果是一样的。而我的 redis 实例实际上不会占用太多内存。

最佳答案

一般来说,与 libc malloc 相比,jemalloc 或 tcmalloc 的碎片更少。这是由于 4 个因素:

  • jemalloc 和 tcmalloc 的更精细的分配类。它减少了内部碎片,尤其是当 Redis 必须分配大量非常小的对象时。

  • 更好的算法和数据结构来防止外部碎片(尤其是对于 jemalloc)。显然, yield 取决于您的长期内存分配模式。

  • 支持“malloc 大小”。一些分配器提供了一个 API 来返回已分配内存的大小。对于 glibc (Linux),malloc 不具备此功能,因此通过向每个分配的内存块显式添加额外前缀来模拟它。它增加了内部碎片。使用 jemalloc 和 tcmalloc(或使用 BSD libc malloc),没有这样的 开销。

  • jemalloc(和 tcmalloc 有一些设置更改)可以比 glibc 更积极地向操作系统释放内存 - 但同样,它取决于分配模式。

现在,如何获得不一致的 mem_fragmentation_ratio 值?

the INFO documentation 中所述,mem_fragmentation_ratio 值计算为进程的内存驻留集大小(RSS,由操作系统测量)与 Redis 使用分配器分配的字节总数之间的比率。

现在,如果使用 libc 分配了更多内存(与 jemalloc、tcmalloc 相比),或者如果在基准测试期间系统上的某些其他进程使用了​​更多内存,Redis 内存可能会被操作系统换出。它将减少 RSS(因为 Redis 内存的一部分将不再位于主内存中)。由此产生的碎片率将小于 1。

换句话说,只有当您确定 Redis 内存没有被操作系统换出时,这个比率才有意义(如果不是这样,您无论如何都会遇到性能问题)。

关于memory-management - 为什么 Redis 内存碎片小于 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18097670/

相关文章:

c - 在 C 中实现隔离内存存储 (malloc)

.net - C# 如何管理循环内由新运算符分配的内存?

c++ - 使固定大小的 block 池分配器适应某些 STL 容器

php - Redis nodejs 获取过滤器

c# - Redis全文搜索与C#

c - 标准 C 库和系统调用如何协同工作?

firebase - AWS Lambda错误: Failed to load gRPC binary module because it was not installed for the current system

c# - 在 .NET 等托管环境中是否可能发生内存泄漏?

c - 来自 realloc() 的奇怪行为

redis - 如何知道Redis中的从站连接到主站?