node.js Память RSS растет со временем, несмотря на довольно стабильные размеры кучи

#node.js #memory-leaks

#node.js #утечки памяти

Вопрос:

У меня есть node.js приложение, в котором использование памяти RSS, похоже, продолжает расти, несмотря на то, что heapUsed / heapTotal остаются относительно постоянными.

Вот график трех измерений памяти, проведенных за неделю (из process.memoryUsage() ):

график памяти

Вы можете заметить, что существует несколько циклический шаблон — это соответствует активности приложения в течение каждого дня.

На самом деле, похоже, наблюдается небольшой рост кучи, хотя он и близко не соответствует росту RSS. Поэтому я время от времени собирал дампы кучи (используя node-heapdump) и использовал функцию сравнения кучи Chrome для поиска утечек.
Одно из таких сравнений может выглядеть следующим образом (сортируется по дельте размера в порядке убывания):

дамп кучи

То, что на самом деле отображается, зависит от того, когда был сделан снимок (например, иногда выделяется больше объектов буфера и т. Д.) — Здесь я попытался взять образец, который лучше всего демонстрирует проблему.

Первое, что следует отметить, это то, что размеры с левой стороны (203 МБ против 345 МБ) намного выше, чем размеры кучи, показанные на графике. Во-вторых, дельта размера явно не соответствует разнице в 142 МБ. Фактически, при сортировке по дельте размера в порядке возрастания многие объекты были освобождены, что означает, что куча должна быть меньше!

У кого-нибудь есть идеи по:

  • почему это так? (RSS постоянно растет при стабильном размере кучи)
  • как я могу предотвратить это, если не перезапускать сервер время от времени?

Другие подробности:
Версия узла: 0.10.28
ОС: Ubuntu 12.04, 64-разрядная

Обновление: список используемых модулей:

Спасибо за чтение.

Комментарии:

1. Какие модули вы используете? Есть ли какие-либо из них скомпилированные дополнения?

2. Спасибо за комментарий, добавлен список модулей выше. Я считаю, что только node-time, webkit-devtools-agent и heapdump являются скомпилированными модулями, причем активно используется только node-time. скомпилированный компонент node-time — это очень простое время. h-оболочка.

3. @zinga Вы нашли причину этого? Страдает от той же проблемы

4. К сожалению, нет — проблема на самом деле усугубилась, когда я обновился до node v0.12, а затем исчезла, когда я перешел на node v4. Дополнительные скомпилированные модули не добавлены, поэтому я обвиняю node в утечке памяти. Если вы считаете, что это не скомпилированный модуль, попробуйте разные версии node, я думаю…

5.Мы все еще исследуем аналогичную проблему, но мы столкнулись с этим: обычно только массивы и строки могут иметь значительный малый размер. Однако строки и внешние массивы часто имеют основное хранилище в памяти средства визуализации, предоставляя доступ только к небольшому объекту-оболочке в куче JavaScript. Источник можно найти здесь в разделе «Малый размер«.

Ответ №1:

Разница, которую вы видите между использованием RSS и использованием кучи, — это буферы.

«Буфер похож на массив целых чисел, но соответствует необработанному распределению памяти за пределами кучи V8» https://nodejs.org/api/buffer.html#buffer_buffer

Комментарии:

1. Спасибо за объяснение. Однако буферы фактически отображаются в дампе кучи (включая используемое пространство), и они не объясняют разницу. Очевидно, что это определенно не будет полной разницей — node, V8 и другой машинный код сами потребляют память, что увеличивает RSS без увеличения размера кучи JS.