简体   繁体   English

ERlang HEAP溢出

[英]ERlang HEAP overflow

I have quite a program.. 我有一个程序。

Its almost complete.. 它几乎完成了。

However I am seeing a heap crash after about 12 hours of running. 但是,运行约12小时后,我看到堆崩溃。

I remember hearing that you can't program erlang in a certain way if not when you recurse the stack builds up. 我记得曾经听说过,当递归堆栈建立时,您不能以某种方式对erlang进行编程。 Can anyone provide an example of that?? 谁能提供一个例子吗?

And also is there any way to have a realtime monitor of what process' are stacking up? 还有什么办法可以实时监视正在堆叠的进程?

Regards 问候

EDIT - What about 编辑-怎么样

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

     _ -> continue
  end,
  loop().

Even your edit is not tail-recursive: 甚至您的编辑也不是尾递归的:

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

The order of execution for one function is: receive ... end, loop() . 一个函数的执行顺序为: receive ... end, loop() Now, if you get a {sys, _} message, loop/0 will be called from within the receive, transforming the order of execution above into something equivalent to: 现在,如果收到一条{sys, _}消息,则将从接收中调用loop/0将上面的执行顺序转换为等效于:

 loop() ->
      receive
          loop() ->
               receive
                  ...
               end,
               loop(),
      end,
      loop() ->
         ...

The problem is that if you call loop() from within the receive, the VM still has to store the return point in order to run the loop() in place after the receive . 问题是,如果您从接收内部调用loop() ,则VM仍必须存储返回点,以便在receive之后在适当位置运行loop()

To make your function tail-recursive, you would need to do either: 要使函数尾部递归,您需要执行以下任一操作:

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

or 要么

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

Where calling loop() really is always the last thing to be done in the function. 实际上,调用loop() 始终是函数中要做的最后一件事。

The process loop must be tail-recursive. 流程循环必须是尾递归的。

DO NOT 不要

loop() -> 
  receive
     {sys, Msg} ->
         handle_sys_msg(Msg),
         loop();
     {From, Msg} ->
          Reply = handle_msg(Msg),
          From ! Reply,
          loop()
  end,
  io:format("Message is processed~n", []).

See: http://www.erlang.org/doc/efficiency_guide/processes.html 请参阅: http : //www.erlang.org/doc/efficiency_guide/processes.html

Something like this could be used for monitoring the current heap usage of processes in you system. 诸如此类的东西可用于监视系统中进程的当前堆使用情况。 Just put it in a printout in a looping gen_server or just run it in the shell every once in a while. 只需将其放入循环gen_server的打印输出中,或不时在外壳中运行它即可。

lists:reverse(lists:keysort(2,
   [{Pid,catch element(2,process_info(Pid,total_heap_size))} || Pid <- processes()])).

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM