找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 146|回复: 0

帮忙分析下这段 nodejs 代码的内存泄漏原因

[复制链接]

1091

主题

0

回帖

3307

积分

管理员

积分
3307
发表于 2023-12-8 09:50:11 | 显示全部楼层 |阅读模式
有一个实时应用,使用 nodejs 编写,会每隔一段时间调用远程 grpc ,大概每秒 1 、2 次这样的调用。上线一个月后发现服务器内存占用越来越大。大概占用了 14GB 的内存吧。用 iotop 发现 node 内存炸了。
使用了 alinode dump heap 了,发现了有一个 promisifyCall 占用了大量内存,疑似泄露。
调用链是
自身大小(字节) 总大小(字节)      函数
0              524600         processTicksAndRejections   internal/process/task_queues.js
0              524600           updateStatus              我自己的文件
0              524600              publish                这里调用了 grpc 导出的函数
524600         524600                promisifyCall        这里应该就是泄露的函数了

promisifyCall 来自于 https://github.com/bojand/promisify-call ,看了下是被 grpcCaller 引用的
https://github.com/bojand/grpc-caller 。项目中使用了 grpcCaller 去调用 grpc 方法。
const res = await grpcCallerInstance.publish(req);

接着这个 publish 操作就走到promisifyCall中去了
promisifyCall 的定义看了下,https://github.com/bojand/promisify-call/blob/master/index.js
const wc = require('with-callback')

/**
* Promisifies the call to <code>fn</code> if appropriate given the arguments.
* Calls the function <code>fn</code> either using callback style if last argument is a function.
* If last argument is not a function, <code>fn</code> is called returning a promise.
* This lets you create API that can be called in either fashions.
* @param  {Object}   ctx  context / this
* @param  {Function} fn   The function to call
* @param  {arguments}   args Arguments
* @return {undefined|*|Promise}  Promise if promisified
*/
function promisifyCall (ctx, fn) {
  const args = []
  args.push.apply(args, arguments)
  args.splice(0, 2)
  // check if last (callback) argument is being pased in explicitly
  // as it might be undefined or null, in which case we'll replace it
  const same = fn.length && args.length === fn.length
  const lastIndex = same ? fn.length - 1 : args.length - 1
  const lastArg = args && args.length > 0 ? args[lastIndex] : null
  const cb = typeof lastArg === 'function' ? lastArg : null

  if (cb) {
    return fn.apply(ctx, args)
  }

  return wc(callback => {
    same
      ? args[lastIndex] = callback
      : args.push(callback)
    fn.apply(ctx, args)
  })
}

隐约感觉里面的 args 变量可能会导致泄露。但还是没想明白怎样才会发生这个泄露。

我可能搞错了,524600 字节并不大。再抓一晚上数据看看。
Node.js 不用 buffer 不是最大内存 1.4GB 吗,兄弟你这 14GB 怎么搞出来的
@zhzbql 同时起了多个进程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|张迁碑

GMT+8, 2024-10-31 19:22 , Processed in 0.095620 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表