2013-11-14 4 views
2

В течение более месяца я борюсь с очень неприятной проблемой утечки памяти, и я понятия не имею, как ее решить.Утечка памяти в приложении для искателя node.js

Я пишу веб-гуру общего назначения на основе: http, async, cheerio и nano. С самого начала я боролся с утечкой памяти, которую было очень сложно изолировать. Я знаю, что можно сделать heapdump и проанализировать его с помощью Google Chrome, но я не могу понять результат. Обычно это куча бессмысленных строк и объектов, приводящих к некоторым анонимным функциям, которые ничего не говорят мне (это может быть недостаток опыта на моей стороне).

В конце концов я пришел к выводу, что библиотека, которую я использовал в то время (jQuery), имела проблемы, и я заменил ее на Cheerio. У меня сложилось впечатление, что Черио решил проблему, но теперь я уверен, что она сделала ее менее драматичной.

Вы можете найти мой код по адресу: https://github.com/lukaszkujawa/node-web-crawler. Я понимаю, что может быть много кода для анализа, но, возможно, я делаю что-то глупое, что может быть очевидным. Я подозреваю, что основной класс агента, который выполняет HTTP-запросы https://github.com/lukaszkujawa/node-web-crawler/blob/master/webcrawler/agent.js из нескольких «потоков» (с async.queue).

Если вы хотите запустить код требует CouchDB и после npm install сделать:

$ node crawler.js -c conf.example.json

Я знаю, что узел не сойти с ума от сбора мусора, но после 10мина тяжелого ползания используемой памяти может легко переходите на 1 ГБ.

(проверено с v0.10.21 и v0.10.22)

+0

Вы сохранили меня с этим предложением: «Это небольшая утечка памяти сама по себе, но несущественная. Странно, что строка каким-то образом связана со всем объектом HTML и сохраняет ссылку на нее». Я потратил три полных дня, пытаясь найти то, что протекал в моем коде, и я обнаружил, что это связано с массивом URL-адресов. Затем я увидел это сообщение и попытался сломать ссылки, используя 'JSON.parse (JSON.stringify (item))'. Моя утечка памяти мгновенно и волшебным образом исчезла. Мне жаль, что я не видел этот пост раньше. –

ответ

4

Для чего это стоит, использование памяти узла будет расти и расти, даже если фактическая б память не очень велика. Это для оптимизации от имени двигателя V8. Чтобы увидеть реальное использование памяти (чтобы определить, есть ли на самом деле утечка памяти) загляните этот код (или нечто подобное) в ваше приложение:

setInterval(function() { 
    if (typeof gc === 'function') { 
     gc(); 
    } 
    applog.debug('Memory Usage', process.memoryUsage()); 
}, 60000); 

Run node --expose-gc yourApp.js. Каждую минуту будет строка журнала, отражающая использование реальной памяти сразу после принудительной сборки мусора. Я обнаружил, что наблюдение за результатами этого времени является хорошим способом определить, есть ли утечка.

Если вы обнаружили утечку, лучшим способом, который я нашел для его отладки, является устранение больших разделов вашего кода за раз. Если утечка исчезнет, ​​верните ее и устраните меньшую часть. Используйте этот метод, чтобы сузить его до места возникновения проблемы. Закрытие является общим источником, но также проверять, что ссылки в других местах не могут быть очищены. Многие сетевые приложения будут прикреплять обработчики для сокетов, которые не будут немедленно уничтожены.

+0

Это очень полезный совет. Спасибо вам за это. –

+0

FYI.Проблема, безусловно, есть: {Новости: 134713344, heapTotal: 94329600, heapUsed: 27132928} {RSS: 226758656, heapTotal: 180926016, heapUsed: 109045368} {RSS: 296513536, heapTotal: 253418872, heapUsed: 140803152} {Новости : 311947264, heapTotal: 264942592, heapUsed: 147487528} { Новости: 354574336, heapTotal: 294030992, heapUsed: 190165824} { Новости: 487866368, heapTotal: 412446680, heapUsed: 220472240} –

+0

@LukaszKujawa вы также можете проверить memwatch. https://github.com/lloyd/node-memwatch – pllee

Смежные вопросы