Утечка памяти, наблюдаемая в приложении Erlang - PullRequest
4 голосов
/ 18 февраля 2011

Позвольте мне задать свой вопрос так же просто, как показано ниже.У меня есть программное обеспечение для сетевого маршрутизатора, встроенное в Erlang, но в конкретном сценарии я наблюдаю очень высокий рост памяти, как показывает VM.

У меня есть один процесс, который получает двоичный пакет от другого процесса из сокета.

Этот процесс анализирует двоичный пакет и передает двоичный пакет gen_server (вызывается handle_cast)

gen_server снова сохраняет некоторую информацию в таблице ETS и отправляет пакет на равноправный сервер.

Когда одноранговый сервер отвечает обратно, запись от ETS удаляется, и gen_server отвечает обратно на первый процесс

Также, если первый процесс (который отправил пакет gen_server) получает тайм-аут через 5 секунд, ожидая ответа от gen_server, он также удаляет запись ETS в gen_server и завершает работу.

Теперь я наблюдаю высокий рост памяти, когда много событий истекает по тайм-ауту (из-за недоступности однорангового сервера) и из того, что я исследовал, это "** двоичные **" и "**process_used ** ", заданный командой erlang: memory, которая использует большую часть памяти.

но то же самое не верно, когда события обрабатываются успешно.

Ответы [ 3 ]

9 голосов
/ 18 февраля 2011

Потеря памяти может быть в основном только в трех местах:

  1. Состояние вашего gen_server

    • посмотрите на свое состояние, выясните, есть ли там что-то большое или растущее
  2. Ваши почтовые ящики процессов

    • проследите за тем, чтобы в обычном receive s * Any -> предложении существовал какой-то способ всегда слить несогласованные сообщения (для обратного вызова gen_server handle_info).

    • , если почтовый ящик только временно заполняется, вероятно, из-за того, что процесс приема слишком медленный для скорости создаваемых сообщений. Обычно это проблема асинхронного взаимодействия. Если это только временные всплески, которые ничего не ломают, это может быть предназначено.

      • В этом случае вы можете оптимизировать процесс получения

      • или исправьте ваш протокол, чтобы использовать меньше сообщений

      • если у вас есть несколько функций, которые принимают некоторые сообщения, убедитесь, что все принимающие части вызываются регулярно Не забудьте пункты Any ->.

    • Имейте в виду, что во время обработки в обратном вызове gen_servers никакие сообщения не будут получены, поэтому, если вам потребуется больше времени в обратном вызове, что может потребоваться, асинхронные сообщения могут накапливаться (например, случайное поступление сообщений + фиксированное время обработки) создает неограниченную растущую очередь, подробнее см. Теория очередей

  3. В вашей таблице ETS

    • может быть информация в ETS не будет полностью удалена? Забыли что-то удалить в определенных случаях?
7 голосов
/ 19 февраля 2011

активируйте GC вручную и посмотрите, что происходит с памятью.

[garbage_collect(Pid) || Pid <- processes()] 
3 голосов
/ 18 февраля 2011

Скорее всего, вы оставляете запущенными процессы с ссылками на двоичные файлы.Если процесс умирает, вся память, связанная с этим процессом, будет очищена (включая все двоичные файлы, которые принадлежали только этому процессу).

Если у вас все еще есть утечка двоичных файлов, это означает, что у вас есть какой-то долго работающий процесс (сервер, singleton и т. д.), который хранит ссылки на двоичные файлы либо в состоянии процесса, либо с помощью не хвостовых рекурсивных функций.Удостоверьтесь, что вы очищаете свое состояние, как только время процесса истекает, или они умирают.Также убедитесь, что вы не оставляете ссылки на двоичные файлы в куче, используя не хвостовые рекурсивные вызовы.

...