nodejsを使用して、外部APIからmongodbにデータを保存しようとしています。スクリプトは非常に軽量に感じますが、何らかの理由で大量の RAM を使用しています (からtop):
 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND 
 2626 root      20   0  756m 113m 7148 S  6.5 11.4   3:11.74 nodejs  
これは、疑似コードでスクリプトが行うことです。
each 5 seconds
  fetch 3 JSON lists through an API
    for all new items in list
      store in mongo
[編集] JSON リストはおよそです。それぞれ10kb。したがって、アイテムを処理するまでそれをメモリに保持する必要はないと思います。[/編集]
(軽い)依存関係は次のとおりです。
- クエリ文字列
- https
- 下線
- mongodb (ネイティブ クライアント)
- 一瞬
私はそれを単純な関数として書きましたが、返すときに、使用したすべてのメモリを返す必要がありますか?
スクリプト全体は次のとおりです。
var querystring = require("querystring");
var https = require('https');
var fetch = function(cur, callback) {
  cur = cur.toLowerCase().replace('/', '_');
  var options = {
    host: 'data.fxbtc.com',
    path: '/api?op=query_last_trades&count=100&symbol=' + cur,
    method: 'GET',
    headers: {
      'User-Agent': 'Mozilla/4.0 (compatible; node.js client)'
    }
  };
  var req = https.request(options, function(res) {
    res.setEncoding('utf8');
    var buffer = '';
    res.on('data', function(data) {
      buffer += data;
    });
    res.on('end', function() {
      try {
        var json = JSON.parse(buffer);
      } catch (err) {
        return callback(err);
      }
      callback(null, json);
    });
  });
  req.end();
}
var currencies = [
  'BTC/CNY',
  'LTC/CNY',
  'LTC/BTC'
];
var LAST_TRADE = {
  'BTC/CNY': 0,
  'LTC/CNY': 0,
  'LTC/BTC': 0
}
var _ = require('underscore');
var mongo = require('mongodb');
var moment = require('moment');
var init = function(next) {
  mongo.connect('mongodb://127.0.0.1:27017/coindata', next);
}
var now = function() {
  return moment().format('YYYY-MM-DD HH:mm:ss');
}
console.log(now(), 'STARTING');
setInterval(function() {
  console.log(now(), 'alive')
}, 60000)
var collections = {};
var forever = function(err, db) {
  if(err) throw err;
  _.each(currencies, function(cur, i) {
    collections[cur] = db.collection('fxbtc_' + cur);
    collections[cur].ensureIndex({fid: 1}, {unique: true}, console.log);
    setTimeout(function() {
      console.log(now(), 'registering', cur);
      setInterval(check(cur), 5 * 1000);
    }, i * 1000);
  });
}
var check = function(cur) {
  return function() {
    fetch(cur, function(err, trades) {
      if(err) return console.log(now(), 'ERROR-FETCH', err);
      trades = _.map(trades.datas, function(trade) {
        return {
          date: new Date(trade.date * 1000),
          price: parseFloat(trade.rate),
          amount: parseFloat(trade.vol),
          fid: parseInt(trade.ticket)
        }
      });
      trades = _.filter(trades, function(trade) {
        return trade.fid > LAST_TRADE[cur];
      });
      var fids = _.pluck(trades, 'fid');
      fids.push(LAST_TRADE[cur]);
      LAST_TRADE[cur] = _.max(fids);
      if(!trades.length)
        return;
      console.log(now(), 'storing:', trades.length, 'in', cur);
      collections[cur].insert(trades, function(err, docs) {
        if(err && err.code !== 11000) console.log(now(), 'ERROR-STORE', err);
      });
    });
  }
}
init(forever);
このスクリプトに明らかなメモリ リークはありますか? 使用されているすべてのメモリのソースを見つけるにはどうすればよいですか?