我在expressjs中间件中的闭包是否导致内存泄漏?

问题描述 投票:0回答:1

我有一个中间件函数,可以在请求对象上设置一些实用程序客户端。当响应完成时,它会破坏连接。

export const setRequestUtils = (req: Request, res: Response, next: NextFunction) => {
  req.dynamoClient = new DynamoStorage();
  req.s3Client = new S3();

  res.on('close', () => {
    req.dynamoClient.destroy();
    req.s3Client.destroy();
  });
  next();
};

这是托管在 ECS 集群上的,我注意到当服务空闲时 ECS 将调用该服务。这些调用似乎导致集群上的内存使用量上升

express 或 Node 是否将

req
保留在闭包中而不对其进行垃圾收集?

编辑:

关闭似乎是问题所在。删除它后,每次从 ECS 执行 ping 操作后,内存都会回到其基线

有没有办法释放闭包的内存?

node.js express garbage-collection closures
1个回答
0
投票

在中间件函数中,您将事件侦听器附加到响应对象(res.on('close', ...))。这将创建一个捕获对 req、req.dynamoClient 和 req.s3Client 的引用的闭包。这些引用可以阻止这些对象的垃圾收集,直到事件侦听器被删除或响应对象被销毁。由于您注意到内存问题,这些关闭很可能会随着时间的推移而累积,特别是当 ECS 频繁调用您的服务时。
为了缓解此问题,您可以在不再需要事件侦听器时将其删除。您还可以尝试使用 res.once() 而不是 res.on() 以确保事件侦听器仅触发一次。这应该可以防止保留任何不必要的参考。

  res.once('close', () => {
    req.dynamoClient.destroy();
    req.s3Client.destroy();
    // remove event listeners to prevent memory leaks
    res.removeAllListeners('close');
  });
© www.soinside.com 2019 - 2024. All rights reserved.