【问题标题】:Memory of type "root-set" reallocation Error - Erlang“根集”类型的内存重新分配错误 - Erlang
【发布时间】:2011-11-04 11:27:32
【问题描述】:

我一直在运行一个加密密集型应用程序,它生成伪随机字符串,具有特殊的结构和数学要求。在过去的 8 天里,它为每个节点生成了大约 170 万个凭证号。生成过程是 CPU 密集型的,内存要求非常低。 在 OTP-14B02 上运行的 Mnesia 是存储数据库,生成是在每个虚拟机中完成的。我在集群中有 3 个节点,所有 mnesia 表 disc_only_copies 类型。突然,随着 Solaris 机器上的活动增加(其他用户远程登录并启动 web 服务器、ftp 会话和其他任务),我的 bash shell 开始报告
fork: not enough space 错误。

我的 erlang Vms 也出现了以下错误:

崩溃转储被写入:erl_crash.dump
temp_alloc:无法重新分配 8388608 字节的内存(“root_set”类型)。

通常,我们得到内存分配错误,而不是memory re-location errors,通常"heap" 类型的内存是问题所在。这次报告的内存类型是"root-set"

Qn 1. 这是什么"root-set" 内存?

Qn 2. 它与 CPU 密集型活动有关吗? (为什么要问这个是当我开始任务时,机器响应说鼠标或键盘中断太慢意味着 CPU 太忙或其他一些我现在无法解释的问题)

Qn 3. 可以避免这样的错误吗?如何 ?

【问题讨论】:

    标签: linux erlang solaris


    【解决方案1】:

    fork: not enough space 消息表明这是操作系统设置的问题,但是:

    Q1 - 根集

    根集是垃圾收集器在搜索堆中活动的数据时使用的起点。它通常从 VM 的寄存器开始,然后从堆栈开始,如果堆栈具有对仍需要处于活动状态的堆数据的引用。我不知道 Erlang 中可能还有其他根源,但这些是您开始的基本内容。

    恰好是 8 兆字节空间的重新分配错误可能意味着两件事之一。要么堆中没有 8 MB 可用空间,要么堆碎片化得面目全非,因此虽然其中有 8 MB,但没有连续的此类空间。

    Q2 - CPU 活动影响

    问题与 CPU 本身无关。您的内存不足。较大的根集可能表明您正在进行一些非常深的递归,其中您保留了大量指向数据的指针。您也许可以重写代码,使其在运行时进行尾部调用并使用更少的内存。

    您应该更担心键盘和鼠标的缓慢响应时间。这可能表明有些事情是不对的。进程运行时,vmstat 1、sysstat、htop、dstat 或类似的显示有什么奇怪的吗?由于内存受限,您还在寻找内核或 C libc 是否在这里做一些奇怪的事情。

    Q3 - 如何修复

    如果不了解应用程序正在做什么,我不知道如何修复它。由于您有故障转储,您的第一反应应该是使用故障转储查看器并查看转储。目标是找到一个使用大量内存的进程,或者一个具有深堆栈的进程。从那里开始,您可以寻求限制该进程正在使用的内存量。要么重写代码以便它可以更早地释放内存,要么调整进程的垃圾收集设置(参见 erlang 手册页中的 spawn 选项),或者向系统添加更多内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-29
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      • 2017-11-21
      • 2020-11-04
      相关资源
      最近更新 更多