ERlang HEAP переполнение - PullRequest
       3

ERlang HEAP переполнение

1 голос
/ 18 ноября 2010

У меня довольно программа ..

Его почти завершено ..

Однако я вижу сбой кучи примерно через 12 часов работы.

Я помню, что слышал, что вы не можете запрограммировать erlang определенным образом, если нет, когда вы повторяете накопление стека. Кто-нибудь может привести пример этого?

А также есть ли способ иметь в реальном времени монитор того, какие процессы складываются?

Привет

РЕДАКТИРОВАТЬ - Как насчет

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

     _ -> continue
  end,
  loop().

Ответы [ 3 ]

8 голосов
/ 18 ноября 2010

Даже ваша правка не хвостовая рекурсия:

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, _}, из получателя будет вызван loop/0, преобразующий вышеприведенный порядок выполнения во что-то эквивалентное:

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

Проблема в том, что если вы вызываете loop() изнутри приема, виртуальная машина все еще должна сохранять точку возврата, чтобы запустить loop() на месте после receive.

Чтобы сделать вашу функцию хвостовой рекурсивной, вам необходимовыполните:

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

или

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

Где вызов loop() действительно всегда - последнее, что нужно сделать в функции.

2 голосов
/ 18 ноября 2010

Цикл процесса должен быть хвост-рекурсивным.

НЕ

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

См .: http://www.erlang.org/doc/efficiency_guide/processes.html

1 голос
/ 18 ноября 2010

Нечто подобное можно использовать для мониторинга текущего использования кучи процессов в вашей системе.Просто поместите его в распечатку в зацикленном gen_server или просто запускайте его в оболочке время от времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...