【问题标题】:Cannot allocate 298930300 bytes of memory (of type "old_heap")无法分配 298930300 字节的内存(“old_heap”类型)
【发布时间】:2012-06-18 01:56:00
【问题描述】:

在对我的 erlang 服务器进行负载测试时,使用 +P(最大并发进程数)增加进程数(100、200、3000,...),并让 10 个进程向其余进程发送 1 条消息在创建的进程中,我在 erlang 控制台上收到一条消息:

“故障转储已写入:erl_crash.dump。eheap_alloc:无法分配 298930300 字节的内存(类型为“old_heap”)。异常终止”。

我使用的是 Windows XP。当我创建进程(它正在工作)时没有问题。崩溃发生在进程开始通信(发送 hi 和接收 hello)之后,这是我唯一遇到的问题(顺便说一下,+hms 设置了进程的默认堆大小)。

我该如何解决这个问题?

【问题讨论】:

  • 有多少进程最终触发了该错误消息?
  • 你需要查看crash_dump文件,一般写在崩溃的erlang vm的当前工作目录中
  • 如果您的应用程序无法减少产生的进程数量或产生它们的速度,请将消息更改为binary,这样可以减少内存消耗。

标签: erlang


【解决方案1】:

如果有人会发现它作为此类问题的可能原因之一有用(因为我在任何地方都没有找到任何具体答案) 我们在 rabbitmq 服务器上遇到过类似的问题(linux,64 位,持久队列,默认配置的水印)

eheap_alloc:无法分配 yyy 字节的内存(“堆”类型)

eheap_alloc:无法分配 xxx 字节的内存(“old_heap”类型)

问题在于一次重新排队太多消息。我们的“监控”代码使用带有重新排队选项的“获取”消息,而不限制要获取和重新排队的消息数量(在我们的例子中 - 队列中的所有消息都是 4K) 所以有一次它试图将所有这些消息添加回队列,服务器因上述消息而失败。

希望它能为某人节省几个小时。

【讨论】:

    【解决方案2】:

    使用Crashdump Viewer 查看erl_crash.dump 文件:

    /usr/local/lib/erlang/lib/observer-1.0/priv/bin/cdv erl_crash.dump
    

    (对于 Unix 路径表示歉意;您应该能够在 Windows 上的安装中找到 cdv.bat。)

    查看进程列表;以我的经验,通常会有一个非常长的消息队列的过程,而你没想到它。

    【讨论】:

    【解决方案3】:

    您的内存不足。尝试减小默认堆大小或限制您启动的进程数。

    更高级的解决方案包括分析您的应用程序,看看您是否可以节省一些内存,例如更好地共享二进制文件或减少使用列表和大型消息(这会将数据复制到发送到的每个进程)。

    【讨论】:

    • “减小”默认堆大小是什么意思?
    • 当您增加进程的默认堆大小时,您生成的每个进程将默认使用更多内存。即使你的进程没有消耗那么多内存,你还是会浪费很多。
    【解决方案4】:

    您的一个进程尝试分配近 300MB 内存。您的服务器中可能存在内存泄漏。在适当的设计中,如果不是有意的,您不应该在一个进程中拥有这么大的堆。

    【讨论】:

    • 我改用 16GB RAM 的 Windows7。还是同样的问题。
    • 您使用 64 位 Erlang 虚拟机吗?无论如何,问题出在您的服务器代码中。进程堆或消息队列中有某种未绑定的内存。
    猜你喜欢
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多