Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ERlang堆溢出_Erlang_Heap_Overflow - Fatal编程技术网

ERlang堆溢出

ERlang堆溢出,erlang,heap,overflow,Erlang,Heap,Overflow,我有一个很好的计划 差不多完成了 然而,在运行大约12小时后,我看到堆崩溃 我记得听说,如果在递归堆栈构建时不能以某种方式编程erlang,那么就不能进行编程。有人能举个例子吗 还有,有没有办法对“正在堆积的”过程进行实时监控 问候 编辑-怎么办 loop() -> receive {sys, Msg} -> handle_sys_msg(Msg), loop(); {From, Msg} ->

我有一个很好的计划

差不多完成了

然而,在运行大约12小时后,我看到堆崩溃

我记得听说,如果在递归堆栈构建时不能以某种方式编程erlang,那么就不能进行编程。有人能举个例子吗

还有,有没有办法对“正在堆积的”过程进行实时监控

问候

编辑-怎么办

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

     _ -> continue
  end,
  loop().

流程循环必须是尾部递归的

不要

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", []).

请参阅:

流程循环必须是尾部递归的

不要

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", []).

请参阅:

类似的内容可用于监视系统中进程的当前堆使用情况。只需将其放入循环gen_服务器的打印输出中,或者每隔一段时间在shell中运行一次

lists:reverse(lists:keysort(2,
   [{Pid,catch element(2,process_info(Pid,total_heap_size))} || Pid <- processes()])).
列表:反向(列表:按键端口(2,

[{Pid,catch元素(2,process_info(Pid,total_heap_size))}| | Pid类似的内容可用于监视系统中进程的当前堆使用情况。只需将其放在循环gen_服务器的打印输出中,或者每隔一段时间在shell中运行一次

lists:reverse(lists:keysort(2,
   [{Pid,catch element(2,process_info(Pid,total_heap_size))} || Pid <- processes()])).
列表:反向(列表:按键端口(2,
[{Pid,catch元素(2,process_info(Pid,total_heap_size))}| | Pid即使您的编辑不是尾部递归的:

loop() -> 
  receive
     {sys, Msg} ->
         handle_sys_msg(Msg),
         loop();
     {From, Msg} ->
          Reply = handle_msg(Msg),
          From ! Reply,
          loop();
      _ -> continue 
  end,
  loop().
一个函数的执行顺序是:
receive…end,loop()
。现在,如果您收到一条
{sys,{u}
消息,将从receive内部调用
loop/0
,将上面的执行顺序转换为等同于:

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

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

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

其中调用
loop()
实际上总是函数中最后要做的事情。

即使您的编辑也不是尾部递归的:

loop() -> 
  receive
     {sys, Msg} ->
         handle_sys_msg(Msg),
         loop();
     {From, Msg} ->
          Reply = handle_msg(Msg),
          From ! Reply,
          loop();
      _ -> continue 
  end,
  loop().
一个函数的执行顺序是:
receive…end,loop()
。现在,如果您收到一条
{sys,{u}
消息,将从receive内部调用
loop/0
,将上面的执行顺序转换为等同于:

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

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

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


其中调用
循环()
实际上总是函数中最后要做的事情。

您的编辑是尾部递归的,这意味着它不会在堆栈上构建任何内容。正如@Terrary ADVICE非常正确地指出,您的编辑不是尾部递归的,您的编辑是尾部递归的,这意味着它不会在堆栈上构建任何内容。如@Terrary ADVICE very正确地指出,您的编辑不是尾部递归的。如果接收在try-catch的“try”段中,该怎么办?如果出现异常,VM是否仍存储返回点?(这没有意义,因为异常将在嵌套的“try”段中捕获)是的。在
try…catch
的情况下,如果表达式发生在两者之间,VM将存储堆栈帧,而不是尾部递归。在这种情况下,请使用:
try Res的risk_thing()->recursive_call()catch…end
,这将防止此问题。如果接收处于“try”状态,该怎么办try-catch段?如果出现异常,VM是否仍存储返回点?(这没有意义,因为异常将在嵌套的“try”中捕获)是的。在
try…catch
的情况下,如果表达式发生在两者之间,VM将存储堆栈帧,而不是尾部递归。在这种情况下,使用:
try Res的risk_thing()->recursive_call()catch…end
,这将防止此问题