Неоправданный расход памяти node.js приложением -11


Добрый день, уважаемые хабровчане
Вопрос для людей, глубоко разбирающихся в технологиях и внутренностях ноды по управлению памятью. Процесс отъедает неоправданно много памяти, при этом не течёт



Есть node.js приложение, которое принимает на вход (tcp или unix socket) поток данных, разбивает его на строки, строки передаёт в пул, который в свою очередь раскидывает эти строки по разным файлам. Каждый такой файл полностью реализует интерфейс stream.Writable (но не использует его) и уменьшает свой счётчик length только при выходе из fs.write. Пул также имеет свой буфер, тоже полностью реализует интерфейс stream.Writable (но не использует его). Все строки — объекты типа Buffer, к настоящим строкам данные не приводятся. Одновременных файловых объектов — порядка 3 тысяч.

При работе приложения с некоторым интервалом логирую использование памяти кэшами всех узлов системы. Кэши сокета, парсера строк и самого пула в рабочем режиме всегда пусты, все данные сразу уходят в кэши файлов. Заполнить их удавалось только при нагрузочных тестированиях. Причём кэши соекта и парсера принебрежимо малы, их можно даже не рассматривать. Для кэша пула и кэшей файлов установлен суммарный лимит в 1 ГБ, после которого pool.write начинает возвращать false, и другие участники stream-а ждут от него события «drain».

При нагрузочных тестированиях на локальной машине всё прекрасно работает, общая память процесса даже при полной заполненности всех кэшей не превышает 1.2-1.3 ГБ.

На боевой же по суточным логам объём файловых кэшей не превышает 30 МБ, при этом процесс жрёт 1.4 ГБ оперативки, вместо ожидаемых пусть даже 300-400 МБ. Причём отъедает не сразу, а спустя какое-то время работы, как правило часы. Я сначала думал, что приложение течёт. Сделал heapdump на старте и уже разжиревшему. Оба дампа оказались примерно одинаковыми по объёму и очень маленькими, порядка 5 МБ, и не показали каких бы то ни было утечек. Кроме того, отъев 1.4 ГБ приложение прекращает разрастаться и держится сутками примерно на одной и той же отметке.

Ощущение такое, что приложение сильно фрагментирует память, из-за этого аллокирует её до какого-то своего внутреннего максимума, после чего работает с тем, что есть.

Кто-нибудь сталкивался с подобным поведением нодовских приложений?
Чем объяснить такое странное поведение? Как выяснить, что на самом деле там происходит? Какие инструменты нужно использовать? И что можно сделать, чтобы объёмы памяти были сопоставимы с объёмами входных данных (ограничивать --max-old-space-size не вариант, так как объём входящего потока заранее не известен)?

Окружение — Ubuntu 16.04
Node 0.10 (Знаю, старая, но на более новые пока перейти не можем из-за модулей. К тому же к сути вопроса это отношение не имеет)




К сожалению, не доступен сервер mySQL