[Erlang] обжорство памятью
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 20.01.09 22:35
Оценка:
Hi,

столкнулись с весьма... мнэээ... своеобразным поведением системы. Далее два разных случая (две разных подсистемы).

Первая. Обстановка: сидящий на нескольких сокетах (в тесте — одном) сборщик данных от дофига (от тысячи до десятков тысяч) источников. Каждый источник порождает сообщение "я жив" с дофига (в данном случае это от 30 до 100) параметров. Сборщик принимает данные, разбирает протокол, наводит первичный марафет (например, сверяет seq и ssid), кормит деталями принятого обработчики (по одному на параметр). Обработка параметра может быть достаточно сложна, хотя в типичном случае упрощается до "отклоняется больше дельты => орать немедленно, иначе молчать до таймаута".

В среднем тесте получается 20-30K процессов. На таком тесте при отсутствии всякого назначения режимов памяти до стабилизации потребления памяти оно успевает съесть 200-300M. При ужесточении контроля (мелкий fullsweep_after, hibernate на каждой итерации цикла gen_server и самописного аналога) падает до 50-70M. Однако отладочная печать (стандартный io:format) вызывает неконтролируемый рост потребления памяти, причём даже после зачистки (всех остановили и отстрелили, обстановка максимально близка к девственному состоянию после старта erl) память не очищается (даже на пару мегабайт).

Курение мануалов и исходников на тему GC ничего не дало — если бы на это влияли данные в процессах, оно бы тогда на момент останова заметно сокращалось. Но этого нет. Единственное полуразумное предположение навскидку — буфер консольной выдачи, если он не освобождается. Но что-то я похожего не могу увидеть в коде. Ругаться на проблемы malloc'а тоже смысла мало — оно бы ну в 2 раза увеличило затраты, но и всё.

Вопрос — куда вообще копать, кто может забирать и не отдавать память?

Второй случай значительно более "чистый" в диагностике: раздача статических данных клиентам, данные хранятся в mnesia и вытаскиваются оттуда match_object'ем. Память при этом активно бухнет, до гигабайта (далее срабатывает пока не найденный ограничитель; rlimit'ы и /proc/sys/ проверили, там такого нет). Останов раздатчика и выгрузка мнезии помогает — сокращается до ~50M (по сравнению с гигабайтом это действительно прогресс;)) Но почему она так разбухает всего лишь от лукапов match_object'ами (до гига надо всего лишь ~100 тысяч таких лукапов) и как это лечить?

Erlang+OTP R12B5, AltLinux 5.0. Все приведённые затраты памяти — RSS (VSZ больше, но неинтересно).
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.