ERlang HEAP溢出

BAR*_*BAR 1 heap erlang overflow

我有一个相当的程序..

它几乎完整..

但是我在运行大约12个小时后看到堆崩溃了.

我记得听说你不能以某种方式编写erlang,如果不是你在递归堆栈的时候.谁能提供一个例子?

还有什么方法可以实时监控哪些流程正在堆积?

问候

编辑 - 怎么样

loop() -> 
  receive
     {sys, Msg} ->
         handle_sys_msg(Msg),
         loop();
     {From, Msg} ->
          Reply = handle_msg(Msg),
          From ! Reply,
          loop();

     _ -> continue
  end,
  loop().
Run Code Online (Sandbox Code Playgroud)

I G*_*ICE 8

甚至你的编辑也不是尾递归的:

loop() -> 
  receive
     {sys, Msg} ->
         handle_sys_msg(Msg),
         loop();
     {From, Msg} ->
          Reply = handle_msg(Msg),
          From ! Reply,
          loop();
      _ -> continue 
  end,
  loop().
Run Code Online (Sandbox Code Playgroud)

一个函数的执行顺序是:receive ... end, loop().现在,如果你收到一条{sys, _}消息,loop/0将从接收中调用,将上面的执行顺序转换为相当于:

 loop() ->
      receive
          loop() ->
               receive
                  ...
               end,
               loop(),
      end,
      loop() ->
         ...
Run Code Online (Sandbox Code Playgroud)

问题是如果你loop()从接收中调用,VM仍然必须存储返回点,以便loop()在之后运行到位receive.

要使函数尾递归,您需要执行以下任一操作:

loop() -> 
  receive
     {sys, Msg} ->
         handle_sys_msg(Msg);
     {From, Msg} ->
          Reply = handle_msg(Msg),
          From ! Reply;
      _ -> continue 
  end,
  loop().
Run Code Online (Sandbox Code Playgroud)

要么

loop() -> 
  receive
     {sys, Msg} ->
         handle_sys_msg(Msg),
         loop();
     {From, Msg} ->
          Reply = handle_msg(Msg),
          From ! Reply,
          loop();
      _ -> loop()
  end.
Run Code Online (Sandbox Code Playgroud)

在loop()真正的调用总是在函数中做的最后一件事.