Erlang ETS 内存碎片
Posted
技术标签:
【中文标题】Erlang ETS 内存碎片【英文标题】:Erlang ETS memory fragmentation 【发布时间】: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。我们在当前部署中没有侦察,但将在下一次部署中添加它。此外,无法想象这很重要,但梁在高山容器内运行。
【问题讨论】:
google.cz/search?q=virtual+memory win.tue.nl/~aeb/linux/lk/lk-9.html 谢谢,但这确实不是虚拟内存问题。 erlang上下文中的“VM”是Beam Virtual Machine的简写,是erlang代码执行的过程。虽然是的,虚拟内存不是物理内存,但如果碎片变得非常糟糕,我们最终可能会用完虚拟内存。 erlang-questions - ETS memory fragmentation after deleting data 【参考方案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,因为这完全取决于分配的块的类型、大小等,以及它们的生存时间。
【讨论】:
以上是关于Erlang ETS 内存碎片的主要内容,如果未能解决你的问题,请参考以下文章