NodeJS 内存泄漏/简单回调在哪里?

n1bvdmb6  于 2023-06-05  发布在  Node.js
关注(0)|答案(1)|浏览(197)

我有简单的代码,但它有内存泄漏,我找不到。几分钟后,内存使用量从75 MB增加到180 MB并继续增加。在Node v0.12.7上运行

function tock() {
  extractKeywords('2x Hannets® Akku 3500 mAh für Neato Modell 945-0005, 945-0006, XV Signature Pro, XV Signature, XV Essential, XV-12, XV-15, XV-11', function(err) {
    if (err) {
      console.log(err)
    }

    setImmediate(tock)
  })
}

// run
tock();

function extractKeywords(title, cb) {
  title = title.replace(/[^\w\-_]+/gi, ' ').replace(/\s+/gi, ' ')

  redis.get('keywords_count', function(err, keywords) {
    if(!err) {
      lastKeywordCount = keywords = parseInt(keywords)
    }

    // var keywords = keyword_extractor.extract(title, {
    //   language:"german",
    //   remove_digits: true,
    //   return_changed_case: true,
    //   remove_duplicates: true
    // })
    var keywords = ['keyword1', 'keyword2', 'keyword3', 'keyword4', 'keyword5'].filter(function(keyword) {
      if (keyword.length < 5)
        return false
      return true
    }).map(function(k) {
      return [lastKeywordCount, k]
    }).reduce(function(a,b) {
      return a.concat(b)
    })

    keywords.unshift('keywords')

    cb()

    // var keywords = ['keywords', 0, 'test', 1, 'test1', 1, 'test2', 1, 'test3', 1, 'test4']

    // redis.ZADD(keywords, function(err, count){
    //   if (err){
    //     return cb(err)
    //   }

    //   redis.INCRBY('keywords_count', count, cb)
    // })
  })
}

我尝试了节点检查器,但我不能找出泄漏来自哪里。如果我删除filter/map/reduce/unshift,看起来泄漏消失了,或者泄漏的内存更少了。

piv4azn7

piv4azn71#

这可能实际上不是内存泄漏,有时很难用Node来判断。Node.js使用Google的V8 JavaScript引擎,该引擎实现了垃圾收集器。V8使用的GC算法会尝试尽可能多地占用内存,并且在清理未使用的内存时非常懒惰。因此,Node进程通常会继续增加内存使用,直到GC认为最好释放内存的某个点。请注意,Node进程的硬内存限制为1.4 GB。
有一种方法可以强制GC释放内存,使用--expose-gc标志:

node --expose-gc yourscript.js

然后将此代码添加到应用程序开头的某个位置。这将强制每30秒进行一次垃圾收集。

setInterval(function() {
  global.gc();
  console.log('GC done')
}, 30000);

然后,将代码运行一段时间。如果您的内存仍然随着时间的推移不断增加,那么很可能是合法的内存泄漏。

相关问题