【问题标题】:Why Erlang / Elixir observer memory usage numbers do not add up?为什么 Erlang / Elixir 观察者的内存使用数字不加起来?
【发布时间】:2018-11-06 05:52:30
【问题描述】:

我从 Elixir 开始,并在使用 iex 连接到我的远程生产节点时观察到一些奇怪的行为。

如下面的屏幕截图所示,观察者报告总共有 92 MB 内存在使用中。然而,当你总结进程、原子、二进制文件、代码和 ets 的内存消耗时,它会是:~69 MB

Processes  19.00 MB
    Atoms   0.97 MB (969 kB)
 Binaries  13.00 MB
     Code  28.00 MB
      ETS   7.69 MB (7685 kB)
-------------------
    Total  68.66 MB

那么,我的第一个问题是这额外的 23 MB 内存来自哪里?我很确定这不仅仅是一个报告问题。因为当我查看 Kubernetes pod 的内存消耗时,它是 ~102 MB,这与观察者显示的数字一致。

我唯一能想到的是那些 23 MB 还没有被垃圾收集。我的假设有效吗?如果是这样,那么自此容器启动以来已经 6 小时了。而且我从一开始就一直在监控内存消耗。现在不应该是垃圾收集吗?

第二个问题:我可以对 Erlang VM / Elixir 配置进行调整以优化内存占用吗?

【问题讨论】:

  • 您需要深入了解 VM 以获得准确的数字,但也有堆栈、VM 以及可能会增加分配给进程的页面的算法(很可能是数字对于“总计”)以较大的增量。是否有任何特殊原因需要使用 RAM 的每个字节?通常,我根本不看这些统计数据,我在 RPi 等内存受限的设备上工作了很多......

标签: erlang elixir phoenix-framework


【解决方案1】:

我也一直在尝试解决有关 OTP 应用程序中的内存管理的问题,并且对我特别有用的一个工具是由 Fred Hebert 编写的名为 recon 的库。尤其是 recon_alloc 模块,它提供了有关 Erlang VM 内存使用情况的非常有用的信息。

丢失的兆字节

以下引用直接取自 recon_alloc:memory() 函数的文档,可能会让您了解正在发生的事情:

`allocated' 报告的内存应该与操作系统大致匹配 报告。如果这个数额相差很大,可能是 表示有人直接在 C 中分配内存,在 Erlang 自己的分配器——一个很大的警告信号。目前有 不计入此的三个内存分配来源 value:mseg分配器中缓存的段,分配的任何内存 作为超级载体,并在期间分配的小块内存 在内存分配器初始化之前启动。另请注意 低内存使用可能是内存碎片的标志,其中 建议探索哪个特定分配器有问题。

所以我认为额外的 23 MB 内存使用可能是由一些不希望的分配引起的,或者可能是由于碎片。


调整(非常小心 /!\)

关于你的第二个问题,Erlang 中有一个名为erts_alloc 的工具,它也描述了内存分配器的手动配置。可以通过将命令行标志传递给模拟器来完成,例如:

erl +SOMEFLAG +SOMEOTHERFLAG

但是文档中有一个很大的红色警告,强烈表明弄乱这些标志可能会导致比默认配置更糟糕的行为。

因此,如果这确实是解决问题的唯一方法,我的建议是诉诸这些修改。在这种情况下,有一个关于 Erlang 运行时系统的book 帮助我理解了某些方面,所以我也建议事先阅读它。

注意:这里是在黑暗中拍摄,没有直接回答您的问题,但仔细检查您的二进制文件发生了什么可能很有用,因为我看到报告了 13 MB由观察者。根据它们的大小(小于或大于 64 字节),它们存储在进程堆中或通过引用访问。我遇到了案例 #1,其中有很多小的二进制文件堆积并最终导致我的系统崩溃。


我在尝试解决这些问题时发现了一些其他有用的资源:

  • 这个特定的 sn-p 来自 blog post,也是由 Fred Hebert 撰写的:

[erlang:garbage_collect(Pid) || Pid <- processes()].

它会立即在所有正在运行的进程上触发 GC。就我而言,它创造了奇迹。您也可以添加一个异步调用它的选项,因此您不必阻塞,直到全部完成:

[erlang:garbage_collect(Pid, [{async, RequestId}]) || Pid <- processes()].

希望这会有所帮助:)

【讨论】:

  • 这太棒了!感谢您的详细回复!
  • 很高兴看到还为时不晚!非常欢迎你:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
  • 2018-05-20
  • 2012-02-18
  • 2022-01-12
  • 1970-01-01
相关资源
最近更新 更多