我得到以下警告:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace:
at EventEmitter.<anonymous> (events.js:139:15)
at EventEmitter.<anonymous> (node.js:385:29)
at Server.<anonymous> (server.js:20:17)
at Server.emit (events.js:70:17)
at HTTPParser.onIncoming (http.js:1514:12)
at HTTPParser.onHeadersComplete (http.js:102:31)
at Socket.ondata (http.js:1410:22)
at TCP.onread (net.js:354:27)
我在server.js中写了这样的代码:
http.createServer(
function (req, res) { ... }).listen(3013);
如何解决这个问题?
You said you are using process.on('uncaughtException', callback);
Where are you executing this statement? Is it within the callback passed to http.createServer?If yes, different copy of the same callback will get attached to the uncaughtException event upon each new request, because the function (req, res) { ... } gets executed everytime a new request comes in and so will the statement process.on('uncaughtException', callback);Note that the process object is global to all your requests and adding listeners to its event everytime a new request comes in will not make any sense. You might not want such kind of behaviour. In case you want to attach a new listener for each new request, you should remove all previous listeners attached to the event as they no longer would be required using: process.removeAllListeners('uncaughtException');
节点版本号:v11.10.1
来自堆栈跟踪的警告消息:
process.on('warning', e => console.warn(e.stack));
(node:17905) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 wakeup listeners added. Use emitter.setMaxListeners() to increase limit
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 wakeup listeners added. Use emitter.setMaxListeners() to increase limit
at _addListener (events.js:255:17)
at Connection.addListener (events.js:271:10)
at Connection.Readable.on (_stream_readable.js:826:35)
at Connection.once (events.js:300:8)
at Connection._send (/var/www/html/fleet-node-api/node_modules/http2/lib/protocol/connection.js:355:10)
at processImmediate (timers.js:637:19)
at process.topLevelDomainCallback (domain.js:126:23)
在搜索github问题,文档和创建类似的事件发射器内存泄漏后,由于node-apn模块用于iOS推送通知,观察到此问题。
这就解决了问题:
您应该为每个进程只创建一个Provider
您拥有的证书/密钥对。您不需要创建一个新的
每个通知的提供者。如果你只是发送通知
一个应用程序,那么就不需要一个以上的提供商。
如果你经常在你的应用程序中创建Provider实例,make
当你使用完每个提供者时,一定要调用provider .shutdown()
释放其资源和内存。
每次发送通知时,我都在创建提供者对象,并期望gc将其清除。
I prefer to hunt down and fix problems instead of suppressing logs whenever possible. After a couple days of observing this issue in my app, I realized I was setting listeners on the req.socket in an Express middleware to catch socket io errors that kept popping up. At some point, I learned that that was not necessary, but I kept the listeners around anyway. I just removed them and the error you are experiencing went away. I verified it was the cause by running requests to my server with and without the following middleware:
socketEventsHandler(req, res, next) {
req.socket.on("error", function(err) {
console.error('------REQ ERROR')
console.error(err.stack)
});
res.socket.on("error", function(err) {
console.error('------RES ERROR')
console.error(err.stack)
});
next();
}
删除该中间件将停止您所看到的警告。我会查看您的代码,并尝试找到您可能设置了不需要的侦听器的任何地方。
缺省情况下,任何单个事件最多可以注册10个侦听器。
如果这是你的代码,你可以通过:
const emitter = new EventEmitter()
emitter.setMaxListeners(100)
// or 0 to turn off the limit
emitter.setMaxListeners(0)
但如果这不是你的代码,你可以使用技巧来增加全局默认限制:
require('events').EventEmitter.prototype._maxListeners = 100;
当然,你可以关闭限制,但要小心:
// turn off limits by default (BE CAREFUL)
require('events').EventEmitter.prototype._maxListeners = 0;
顺便说一句。代码应该在应用程序的最开始。
ADD:从节点0.11开始,这段代码也可以改变默认限制:
require('events').EventEmitter.defaultMaxListeners = 0