#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-разрядная
Обновление: список используемых модулей:
- async v0.2.6
- log4js v0.6.2
- mysql v2.0.0-alpha7
- nodemailer v0.4.4
- время узла v0.9.2 (для информации о часовом поясе, не путать с временем узла)
- sockjs v0.3.8
- подчеркивание версии v1.4.4
- использование версии 0.3.9 (для статистики процессора, не используется для использования памяти)
- webkit-devtools-agent v0.2.3 (загружен, но не активирован)
heapdump v0.2.0 загружается при создании дампа.
Спасибо за чтение.
Комментарии:
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.