সম্ভাব্য ইভেন্টইমিটার মেমরি ফাঁস সনাক্ত হয়েছে


231

আমি নিম্নলিখিত সতর্কতা পাচ্ছি:

(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)

আমি সার্ভার.জেজে এই জাতীয় কোড লিখেছি:

http.createServer(
    function (req, res) { ... }).listen(3013);

কিভাবে এটি ঠিক করবেন?


46
process.on('warning', e => console.warn(e.stack));সতর্কতা ডিবাগ করতে ব্যবহার করুন । process.setMaxListeners(0);সতর্কতাটি কোনও কারণে রয়েছে বলে ব্যবহার করবেন না ।
শ্বেতাভ শেখর

ধন্যবাদ. খুব দরকারী নির্দেশ।
আবদুল্লাহ আল ফারুক

এই ত্রুটি আমার উপর ঘটে yarn install। স্ট্যাক ট্রেস যুক্ত করতে আমি এই লাইনটি কোথায় রাখতে পারি?
সোনিক সোল

উত্তর:


94

এটি ব্যাখ্যা করা হয়েছে নোড ইভেন্টএমিটার ডকুমেন্টেশনে

এটি নোডের কোন সংস্করণ? আপনার আর কি কোড আছে? এটি স্বাভাবিক আচরণ নয়।

সংক্ষেপে, এর: process.setMaxListeners(0);

এছাড়াও দেখুন: নোড.জেএস - অনুরোধ - কীভাবে "emitter.setMaxListeners ()"?


1
v0.6.11 ... আমি সমস্ত কিছু করেছি, তবে সতর্কতা এখনও রয়েছে। :(
রিজ

5
আমি ব্যবহার করছিprocess.on('uncaughtException', callback);
রিজ

9
process.setMaxListeners(0); // OMG, its so simple... :D
রিজ

11
আমি সর্বোচ্চ শ্রোতার সীমা সরিয়ে ফেলব না। আপনি সতর্কতা পাবেন না, তবে আপনি মেমরি ফাঁস পাবেন।

15
এই উত্তরটি এই সমস্ত ভোট কীভাবে পেল, এবং সঠিক উত্তর হিসাবে বেছে নেওয়া হয়েছিল? যদিও এটি কাজ করা উচিত, তবে এটি সম্পূর্ণ ভুল!
প্রলিজিক

203

আমি এখানে উল্লেখ করতে চাই যে সতর্কতাটি এখানে একটি কারণ রয়েছে এবং সঠিক সুযোগটি সীমাবদ্ধতা বাড়ছে না তবে আপনি কেন একই ইভেন্টে এত বেশি শ্রোতা যুক্ত করছেন তা নির্ধারণ করার খুব ভাল সুযোগ রয়েছে । কেবলমাত্র সীমা বাড়ান যদি আপনি জানেন যে কেন এত বেশি শ্রোতা যুক্ত হচ্ছে এবং আপনি সত্যই এটি চান তা নিশ্চিত হন।

আমি এই পৃষ্ঠাটি পেয়েছি কারণ আমি এই সতর্কতা পেয়েছি এবং আমার ক্ষেত্রে কিছু কোডে আমি একটি বাগ পেয়েছিলাম যা গ্লোবাল অবজেক্টটিকে ইভেন্টএমিটারে পরিণত করছিল! আমি অবশ্যই বিশ্বব্যাপী সীমাটি বাড়ানোর বিরুদ্ধে পরামর্শ দেব কারণ আপনি চান না যে এই বিষয়গুলি নজরে না আসা।


14
+1 টি। একমত। সতর্কতাটি সম্ভাব্য ফুটা পরিস্থিতি নির্দেশ করে এবং ম্যাকলেসটেনারগুলি নির্বোধভাবে বাড়ানো অগত্যা সমস্যাটি সমাধান করবে না। jongleberry.com
জেরেমিয়া অ্যাডামস

3
আপনি কীভাবে ডিবাগ করতে পারেন "সতর্কতা: সম্ভাব্য ইভেন্টইমিটার মেমরি ফাঁস সনাক্ত হয়েছে 11 ১১ টি ত্রুটি শ্রোতা যুক্ত করেছেন limit আমাদের কী সন্ধান করা উচিত?
ফিল

2
তবে সেই ত্রুটি বার্তার সাথে কোনও স্ট্যাক ট্রেস এবং কোনও কোড নেই। আমি "সতর্কতা" এবং "সম্ভাব্য" তে মূলধন ডাব্লু এবং পি পাই, তাই আমি মনে করি এটি অন্যরকম ত্রুটি হতে পারে। আমার একাধিক ইভেন্ট শোনা দরকার, তবে আমি কেবল কখনও ফোন করি on সব ক্ষেত্রে একবার, তাই সমস্যাটি কী তা নিশ্চিত হন না।
ফিল

2
@ ফিল_1984_ আপনি কি কোনও সমাধান খুঁজে পেয়েছেন? যদি এটি কাজ করে না মনে হয় - stackoverflow.com/questions/38482223/…
Yoni Jah

3
এফওয়াইআই, প্রথম মন্তব্যের লিঙ্ক (jongleberry.com) অফলাইন। এখানে সংরক্ষণাগারিত সংস্করণটি রয়েছে: web.archive.org/web/20180315203155/http://www.jongleberry.com/…
জেফ ওয়ার্ড

76

ডিফল্টরূপে, একক ইভেন্টের জন্য সর্বাধিক 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;

BTW। কোডটি অ্যাপ্লিকেশনটির একেবারে শুরুতে হওয়া উচিত।

যুক্ত করুন: নোড ০.১১ থেকে এই কোডটি ডিফল্ট সীমাটি পরিবর্তন করতেও কাজ করে:

require('events').EventEmitter.defaultMaxListeners = 0

5
নোড 5.6.0 এ এটিই আমার জন্য একমাত্র সমাধান ছিল। অসংখ্য ধন্যবাদ!
অ্যান্ড্রু ফকনার

আমি প্রতিক্রিয়া-স্থানীয়, নোড সংস্করণ 8 ব্যবহার করছি * *। *। এটি আমার পক্ষে কাজ করে না।
থমাস ভ্যালাদেজ

আমার প্রয়োজন ছিল ('ইভেন্টস')।
কার্ল অ্যান্টনি বাল্যওট

72

গৃহীত উত্তরটি কীভাবে সীমা বাড়াতে হবে সে সম্পর্কে শব্দার্থবিজ্ঞান সরবরাহ করে, তবে @ ভোল্ট্রেভো উল্লেখ করেছেন যে সতর্কতার কারণ রয়েছে এবং আপনার কোডটিতে সম্ভবত একটি বাগ রয়েছে।

নিম্নলিখিত বগী কোড বিবেচনা করুন:

//Assume Logger is a module that emits errors
var Logger = require('./Logger.js');

for (var i = 0; i < 11; i++) {
    //BUG: This will cause the warning
    //As the event listener is added in a loop
    Logger.on('error', function (err) {
        console.log('error writing log: ' + err)
    });

    Logger.writeLog('Hello');
}

শ্রোতার যোগ করার সঠিক উপায়টি এখন পর্যবেক্ষণ করুন:

//Good: event listener is not in a loop
Logger.on('error', function (err) {
    console.log('error writing log: ' + err)
});

for (var i = 0; i < 11; i++) {
    Logger.writeLog('Hello');
}

সর্বাধিক তালিকা পরিবর্তন করার আগে আপনার কোডে অনুরূপ সমস্যাগুলি অনুসন্ধান করুন (যা অন্যান্য উত্তরে ব্যাখ্যা করা হয়েছে)


13
এই উত্তরটি গ্রহণ করা উচিত কারণ এটি সতর্কতার পিছনে প্রকৃত কারণ এবং কীভাবে এটি সমাধান করা যায় তা দেখায়, +1
গণেশ কারেয়াদ

এটা সঠিক উত্তর! আমি সত্যই মনে করি যে ম্যাক্সলিসটনার সতর্কতা বেশিরভাগ বগি কোডের কারণে উপস্থিত হয়। আমার ক্ষেত্রে এটি মাইএসকিএল কোড ছিল। আমি এর জন্য একটি স্পষ্টতা দেওয়ার জন্য একটি উত্তর দেওয়ার চেষ্টা করব।
অ্যাড্রিয়ান

25

.on()সঙ্গে প্রতিস্থাপন once()। ব্যবহারonce()ইভেন্ট একই ফাংশন দ্বারা পরিচালিত হয় যখন শ্রোতাদের সরান করে।

এটি যদি এটি ঠিক না করে তবে আপনার প্যাকেজটিতে এটি পুনরায় ইনস্টল করুন j জেসন "রিসেলার": "গিট: //github.com/danwrong/restler.git#9d455ff14c57ddbe263dbbcd0289d76413bfe07d"

এটি রোধকারী 0.10 নোডের সাথে খারাপ ব্যবহারের সাথে করতে হবে। আপনি সমস্যাটি এখানে গিটে বন্ধ দেখতে পেয়েছেন: https://github.com/danwrong/restler/issues/112 তবে, এনপিএম এখনও এটি আপডেট করতে পারে নি, এজন্য আপনাকে গিটের মাথাটি উল্লেখ করতে হবে।


এই পপিটারের কাঠামোটি ব্যবহার করে আমার কোডে এই ত্রুটিটি সমাধান করুন
সি অ্যালোনসো সি অর্টেগা


4

নোড সংস্করণ: 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)

গিথুব সমস্যাগুলি অনুসন্ধান করার পরে, ডকুমেন্টেশনগুলি এবং অনুরূপ ইভেন্ট এমিটার মেমরি ফাঁস তৈরি করার পরে, নোড-এপিএন-এর কারণে এই সমস্যাটি পর্যবেক্ষণ করা হয়েছে আইওএস পুশ নোটিফিকেশনের জন্য ব্যবহৃত মডিউলের ।

এটি এটি সমাধান করেছে:

আপনার কাছে থাকা প্রতিটি শংসাপত্র / কী জুটির জন্য আপনার কেবলমাত্র প্রতি-প্রক্রিয়া সরবরাহকারী তৈরি করা উচিত। প্রতিটি বিজ্ঞপ্তির জন্য আপনাকে নতুন সরবরাহকারী তৈরি করার দরকার নেই। আপনি যদি কেবল একটি অ্যাপে বিজ্ঞপ্তি পাঠাচ্ছেন তবে একাধিক সরবরাহকারীর প্রয়োজন নেই is

যদি আপনি আপনার অ্যাপ্লিকেশনটিতে নিয়মিত সরবরাহকারীর দৃষ্টান্ত তৈরি করে থাকেন তবে প্রতিটি সংস্থানকারীর সংস্থান এবং স্মৃতি ছেড়ে দেওয়ার জন্য আপনি যখন সরবরাহকারীর শাটডাউন () কল করে নিশ্চিত হন।

প্রতিবার বিজ্ঞপ্তি পাঠানোর সময় আমি সরবরাহকারী অবজেক্ট তৈরি করছিলাম এবং জিসিটি এটি পরিষ্কার করার প্রত্যাশা করেছিল।


2

আমার ক্ষেত্রে, এটি child.stderr.pipe(process.stderr)তখনই বলা হয়েছিল যখন আমি সন্তানের 10 (বা তাই) দৃষ্টান্ত শুরু করছিলাম। যে কোনও কিছু, যা কোনও ইভেন্ট হ্যান্ডলারকে একটি LOOP- তে একই ইভেন্টএমিটার অবজেক্টের সাথে সংযুক্ত করে, নোডেজগুলি এই ত্রুটিটি ছুঁড়ে ফেলার কারণ করে।


2

কখনও কখনও এই সতর্কতাগুলি ঘটে যখন এটি করা আমরা কিছু করি না, তবে আমরা যা করতে ভুলে গিয়েছি!

আমি এই সতর্কতার মুখোমুখি হয়েছি যখন আমি এনপিএম দিয়ে ডটেনভ প্যাকেজটি ইনস্টল করেছি, তবে আমার অ্যাপ্লিকেশনটির শুরুতে প্রয়োজনীয় ('ডটেনভ') যোগ করার আগে লোড () বিবৃতিটি যোগ করার আগে বাধা পেয়েছিলাম। আমি যখন প্রকল্পটিতে ফিরে এসেছি, আমি "সম্ভাব্য ইভেন্টইমিটারের মেমরি ফাঁস সনাক্ত হওয়া" সতর্কতা পেতে শুরু করেছি।

আমি ধরে নিয়েছি সমস্যাটি আমার করা কিছু থেকে হয়েছিল, এমন কিছু নয় যা আমি করিনি!

একবার আমি আমার তদারকির বিষয়টি আবিষ্কার করে প্রয়োজনীয় বিবরণ যুক্ত করলে মেমরি ফাঁসের সতর্কতা সাফ হয়ে যায়।


2

আমি যখনই সম্ভব লগগুলিকে দমন করার পরিবর্তে অনুসন্ধান করতে এবং সমস্যাগুলি সমাধান করতে পছন্দ করি। আমার অ্যাপ্লিকেশনটিতে এই সমস্যাটি পর্যবেক্ষণ করার কয়েক দিন পরে, আমি বুঝতে পেরেছি req.socketযে সকেট আইও ত্রুটিগুলি পপআপ করে রাখতে আমি একটি এক্সপ্রেস মিডলওয়্যারটিতে শ্রোতাদের সেট করছি । এক পর্যায়ে, আমি শিখেছি যে এটি প্রয়োজনীয় ছিল না, তবে আমি শ্রোতাদের যেভাবেই রাখি। আমি কেবল সেগুলি সরিয়েছি এবং আপনি যে ত্রুটিটি দেখছেন তা চলে গেছে। আমি নীচের মিডওয়্যারের সাথে বা না করেই আমার সার্ভারে অনুরোধগুলি চালিয়ে যাচাই করেছিলাম:

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();
    }

মিডলওয়্যারটি সরানো আপনি যে সতর্কতাটি দেখছেন তা বন্ধ করে দিয়েছে। আমি আপনার কোডটি ঘুরে দেখব এবং আপনার প্রয়োজন নেই এমন শ্রোতাদের সেট আপ করতে পারে এমন কোনও জায়গায় সন্ধান করার চেষ্টা করব।


1

আমি একই সমস্যা ছিল. এবং সমস্যাটি হয়েছিল কারণ আমি 2 শ্রোতার উপর 8080 পোর্ট শুনেছিলাম।

setMaxListeners() ভাল কাজ করে, তবে আমি এটি সুপারিশ করব না।

সঠিক উপায়টি হ'ল অতিরিক্ত শ্রোতার জন্য আপনার কোডটি পরীক্ষা করুন, শ্রোতা সরিয়ে দিন বা আপনি যে পোর্ট নম্বরটি শুনছেন সেটি পরিবর্তন করা, এটি আমার সমস্যাটিকে স্থির করেছে।


1

আমি শুরু করার আগ পর্যন্ত আমার এটি ছিল grunt watch। অবশেষে সমাধান

watch: {
  options: {
    maxListeners: 99,
    livereload: true
  },
}

বিরক্তিকর বার্তা চলে গেছে।


1

নতুন ব্যবহার করে তৈরি করার আগে আপনাকে সমস্ত শ্রোতা সাফ করতে হবে:

ক্লায়েন্ট সার্ভার

socket.removeAllListeners(); 

ধরে নেওয়া সকেট আপনার ক্লায়েন্ট সকেট / বা তৈরি সার্ভার সকেট।

আপনি যেমন নির্দিষ্ট ইভেন্ট শ্রোতার কাছ থেকেও গ্রাহকতা নিতে পারেন উদাহরণস্বরূপ connectশ্রোতাদের এইরকম অপসারণ :

this.socket.removeAllListeners("connect");

0

আপনি বলেছিলেন আপনি process.on('uncaughtException', callback);
কোথায় ব্যবহার করছেন আপনি এই বিবৃতিটি কার্যকর করছেন? এটি কি কলব্যাকের মধ্যে দিয়ে গেছে http.createServer?
যদি হ্যাঁ, প্রতিটি নতুন অনুরোধের সময় একই কলব্যাকের ভিন্ন অনুলিপি অবিচ্ছিন্ন ধারণা ইভেন্টের সাথে সংযুক্ত হয়ে যাবে , কারণ প্রতিবারই নতুন অনুরোধ আসার পরে function (req, res) { ... }মৃত্যুদন্ড কার্যকর করা হয় এবং তাই বিবৃতিটি process.on('uncaughtException', callback);
নোট করে রাখবেন যে প্রক্রিয়াটি আপনার সমস্ত অনুরোধের কাছে বিশ্বব্যাপী এবং শ্রোতাদের যুক্ত করছে এর ইভেন্টে প্রতিবারই নতুন অনুরোধ আসে তা কোনও অর্থ বোধ করবে না। আপনি এ জাতীয় আচরণ চান না।
আপনি যদি প্রতিটি নতুন অনুরোধের জন্য একটি নতুন শ্রোতা সংযুক্ত করতে চান, আপনার ইভেন্টের সাথে যুক্ত সমস্ত পূর্ববর্তী শ্রোতা অপসারণ করা উচিত কারণ তাদের আর ব্যবহারের প্রয়োজন হবে না:
process.removeAllListeners('uncaughtException');


0

এটির জন্য আমাদের দলের ফিক্সটি আমাদের .npmrc থেকে একটি রেজিস্ট্রি পাথ সরিয়ে ফেলছিল। আরসি ফাইলটিতে আমাদের দুটি পথের উপাধি ছিল এবং একটি হ'ল একটি শিল্প কারখানার দিকে ইঙ্গিত করছিল যা অবনমিত হয়েছে।

আমাদের অ্যাপ্লিকেশনটির আসল কোডের সাথে ত্রুটিটির কিছুই ছিল না তবে আমাদের বিকাশের পরিবেশের সাথে সবকিছু করার ছিল।


0

আমি একই সমস্যার মুখোমুখি হয়েছি, তবে আমি সফলভাবে হ'ল অপেক্ষার অপসারণ সহকারে পরিচালনা করেছি।
এটি সাহায্য করে কিনা তা পরীক্ষা করুন।

ডেটা দৈর্ঘ্য = 25;
আগে: এর
  জন্য (i = 0; i <ডেটা দৈর্ঘ্য; i ++)
      ft sftp.get (রিমোটপথ, fs.createWriteStream ( xyzProject/${data[i].name}));
  } এর

পরে: এর
  জন্য (i = 0; i <ডেটা দৈর্ঘ্য; i++) s
      অপেক্ষা করুন sftp.get (রিমোটপ্যাথ, fs.createWriteStream ( xyzProject/${data[i].name}));
  }


0

RLaaa ধন্যবাদ আসল সমস্যা / মূল কারণটি কীভাবে সমাধান করা যায় সে সম্পর্কে আমাকে ধারণা দেওয়ার । আমার ক্ষেত্রে এটি মাইএসকিউএল বগি কোড ছিল।

সরবরাহ করে আপনি ভিতরে কোড সহ একটি প্রতিশ্রুতি লিখেছিলেন:

pool.getConnection((err, conn) => {

  if(err) reject(err)

  const q = 'SELECT * from `a_table`'

  conn.query(q, [], (err, rows) => {

    conn.release()

    if(err) reject(err)

    // do something
  })

  conn.on('error', (err) => {

     reject(err)
  })
})

খেয়াল করুন conn.on('error')কোডটিতে একটি শ্রোতা রয়েছে। সেই কোডটি শ্রোতাকে বারবার যুক্ত করে বার বার যুক্ত করে যে আপনি কোয়েরিটি কতবার কল করেছেন তার উপর নির্ভর করে। এদিকে if(err) reject(err)একই জিনিস।

তাই আমি conn.on('error')শ্রোতা এবং voila অপসারণ ... সমাধান! আশা করি এটি আপনাকে সহায়তা করবে।


-4

এটি আপনার সার্ভার.জেএস এর প্রথম লাইনে রাখুন (বা আপনার মূল নোড.জেএস অ্যাপ্লিকেশনটি যা রয়েছে):

require('events').EventEmitter.prototype._maxListeners = 0;

এবং ত্রুটি চলে যায় :)


আপনি এটিকে একটি প্রধান ফাইলে রাখার জন্য আমাকে ধারণা দিয়েছেন এবং এটি কার্যকর হয়েছে। আমি এটি একটি ভুল জায়গায় রেখেছিলাম। ধন্যবাদ!
স্কিমকোভিচিচ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.