我有一个erlang集群,其中erlang:memory()'total'从空闲到繁忙时间的天数在2-2.5GB之间。 ETS内存使用量约为440M,无论如何都保持在那里。 ets 中的数据是严重瞬态的,全天完全变化。 明天的数据保证与今天的数据没有共性。
Linux top说beam使用大约10千兆字节。 free -m 'used' 同意这一点(机器实际上只运行 beam)。 系统的整体内存使用量定期增长,例如在 1GB 系统上每天增长 16%。 节点之间存在一些差异,但差异不大,操作系统"使用"内存总是比 erlang:memory() 总数多几倍。
erlang:system_info({分配器, ets_alloc}) 显示 20 个分配器。 大多数都有看起来像这样的数据(命令的完整输出在这里):
{mbcs_pool,[{blocks,2054},
{blocks_size,742672},
{carriers,10},
{carriers_size,17825792}]},
1)这是否意味着742K字节(字?)的内存实际上占用了17M的操作系统内存? 2)正如这篇文章所建议的,我们是否应该在虚拟机参数中添加"+ MEas bf"以减少开销? 3) 我还能做些什么来避免实际内存不足?
这是 R17.5,但我们将在下一次部署(本周)迁移到 R19.3。 当前部署中没有侦察,但将在下一个部署中添加它。 另外,无法想象这很重要,但梁在高山容器内运行。
万一其他人以后遇到这种情况:这实际上不是泄露的内存。
erlang的默认内存分配器策略可能不适合您的使用,具体取决于您的操作,以及 erlang 如何配置分配块。 事实证明,在某些情况下,由于分配器碎片,从 erlang 的角度来看,"释放"内存不一定会立即释放到操作系统。
这里有点解释:http://erlang.org/doc/man/erts_alloc.html
我们当时使用的 erlang 版本的默认分配器策略是 aoffcbf(地址顺序优先适合载体最合适)。 在我们的例子中,这导致了非常高的内存碎片(10 + GB开销)。 在排除这些问题时,erlang:system_info(allocator)
和erlang:system_info({allocator, Alloc})
是您的朋友。 更改为 aobff(地址顺序最合适)可提高内存使用效率。 事实上,只要机器没有耗尽物理内存,这并不重要,但对我们来说,我们正在危险地接近物理极限。 而且您不想开始分页。 使用 aobff,我们从未超过 4GB,即使在节点启动 18 个月之后也是如此。 使用aoffcbf,我们将在几周内通过10GB。
与往常一样,YMMV 完全取决于分配的块的类型、大小等,以及它们的寿命。