【问题标题】:Erlang ETS memory fragmentationErlang ETS 内存碎片
【发布时间】:2018-09-25 15:08:16
【问题描述】:

我有一个 erlang 集群,其中 erlang:memory() 'total' 从空闲到忙碌的时间在 2-2.5GB 之间,日复一日。 ets 内存使用量约为 440M 并且无论如何都保持在那里。 ets 中的数据非常短暂,全天都在变化。保证明天的数据与今天的数据没有共性。

Linux top 说 beam 正在使用大约 10 GB。 free -m 'used' 同意这一点(机器实际上只运行梁)。系统的整体内存使用量定期增长,例如在 16GB 系统上每天增长 1%。节点之间存在一些差异,但差异不大,并且操作系统“已使用”内存始终是 erlang:memory() 总数的几倍。

erlang:system_info({allocator, ets_alloc}) 显示 20 个分配器。大多数数据看起来像这样(命令的完整输出是here):

    {mbcs_pool,[{blocks,2054},
   {blocks_size,742672},
   {carriers,10},
   {carriers_size,17825792}]},

1) 这是否意味着 742K 字节(字?)的内存实际上占用了 17M 的 OS 内存? 2) 正如this post 建议的那样,我们是否应该在VM args 中添加'+MEas bf',以减少开销? 3)我还能做些什么来避免实际内存不足?

这是 R17.5,但我们将在下一次部署(本周)中迁移到 R19.3。我们在当前部署中没有侦察,但将在下一次部署中添加它。此外,无法想象这很重要,但梁在高山容器内运行。

【问题讨论】:

标签: erlang ets


【解决方案1】:

以防其他人稍后遇到这种情况:这实际上并不是内存泄漏。

erlang 的默认内存分配器策略可能不是最适合您的使用,这取决于您所做的事情,以及 erlang 分配块的配置方式。事实证明,在某些情况下,由于分配器碎片,从 erlang 的角度来看,“空闲”内存不一定会立即释放给操作系统。

这里有点解释:http://erlang.org/doc/man/erts_alloc.html

我们当时使用的 erlang 版本的默认分配器策略是 aoffcbf (address order first fit carrier best fit)。在我们的例子中,这导致了非常高的内存碎片(价值 10+GB 的开销)。在解决这些问题时,erlang:system_info(allocator)erlang:system_info({allocator, Alloc}) 是您的朋友。更改为 aobff(地址顺序最合适)会导致更有效的内存使用。事实上,只要机器没有耗尽物理内存,就没有关系,但对我们来说,我们已经危险地接近物理极限了。而且您不想开始分页。使用 aobff,我们从未超过 4GB,即使在节点运行 18 个月后也是如此。使用 aoffcbf 我们将在几周内超过 10GB。

与往常一样,YMMV,因为这完全取决于分配的块的类型、大小等,以及它们的生存时间。

【讨论】:

    猜你喜欢
    • 2013-08-14
    • 2010-10-26
    • 2014-11-30
    • 2012-12-11
    • 2011-01-17
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多