简体   繁体   English

MaxListenersExceededWarning:可能的EventEmitter内存泄漏检测

[英]MaxListenersExceededWarning: Possible EventEmitter memory leak dete

I've read about this error and know what it is, and also know how I can disable it by setting the MaxListeners to 0 . 我已经阅读了这个错误并知道它是什么,并且还知道如何通过将MaxListeners设置为0来禁用它。 But I'd like to know what is causing this error so I can handle it properly. 但我想知道是什么导致了这个错误,所以我可以正确处理它。

Basically here is a robot to check and see if my accounts have new messages or not. 基本上这里是一个机器人来检查我的帐户是否有新消息。 I need to check lots of accounts at once so I wrote this robot to do that. 我需要一次检查很多帐户,所以我写了这个机器人来做到这一点。 I have 4 functions in this code: 我在这段代码中有4个函数:

1 - load_proxy -> reads list of proxies from a file and puts them into an array
2 - load_accounts -> reads list of accounts from a file and puts them into an array
3 - init-> opens a browser , in a while loop fetching accounts and calling the next function  
4 - open_tab-> opens a tab in the browser and checks the account and calles the next function to log the result 

5 - wite_to_file-> writing the result into a text file 


const puppeteer = require('puppeteer');
const fs = require('fs');
const PROXYSTACK = [] ;
const PROXYDB = [] ;
const ACCOUNTSTACK = [] ;
const ACCOUNTDB = [] ;
var   inprogress = false ;


setInterval(()=>load_proxy() , 5000 );
setInterval(()=>load_accounts() , 5000 );
setInterval(function(){

    if( !inprogress)
    {
        init();
    }

} , 2000 );


function load_proxy(){

    var lines = fs.readFileSync('./proxy.txt', 'utf-8')
        .split('\n');

        for(var i = 0 ; i< lines.length ; i++ )
        {
            let line  = lines[i];
            if(line == '' || typeof line == 'undefined')
            {
                continue ;
            }

            line = line.replace('\r' , '');
            if(PROXYDB.includes(line))
                continue ;

            PROXYSTACK.push(line);
            PROXYDB.push(line);

        }

}
function load_accounts(){

    var lines = fs.readFileSync('./accounts.txt', 'utf-8')
        .split('\n');

        for(var i = 0 ; i< lines.length ; i++ )
        {
            let line  = lines[i];
            if(line == '' || typeof line == 'undefined')
            {
                continue ;
            }

            line = line.replace('\r' , '');
            if(ACCOUNTDB.includes(line))
                continue ;

            ACCOUNTDB.push(line);
            ACCOUNTSTACK.push(line);

        }

}



async function init(){

    inprogress = true ;

    if(PROXYSTACK.length <= 0 )
    {
        console.log('========================================= > OUT OF PROXY !!!!');
        inprogress = false ;
        return ;
    }

    if(ACCOUNTSTACK.length <= 0 )
    {
        console.log('========================================= > OUT OF ACCOUNT !!!!');
        inprogress = false ;
        return ;
    }

    var ipport =  PROXYSTACK.pop().replace('\r' , '');
    console.log(` ----> current ${ipport} `);

    var  browser = await puppeteer.launch({headless: true        ,  args: ['--proxy-server=' + ipport  , '--no-sandbox', '--disable-setuid-sandbox' , ]});
    browser._process.once('close', () => {
        console.log(' ------------------------  closed !');
        inprogress = false;
    });
    browser.on('disconnected', () => {
        console.log(' ------------------------  disconnecte !');
        inprogress = false;
    });

    var  mainpage = await browser.newPage();
    await mainpage.setViewport({width: 1200, height: 1000});

    while( inprogress )
    {
        var line_number = ACCOUNTSTACK.length ;
        if(line_number == 0 )
        {
            inprogress = false ;
            break ;
        }
        var account = ACCOUNTSTACK.pop();
        console.log(account);


        var check = await open_tab(account , line_number , mainpage);
        if(check === 'fatalerror')
        {
            console.log('========================================= >  FATAL ERROR CHANGING IP ');
            try {
                await browser.close();
            }
            catch (e) {

            }

            inprogress = false ;
        }


    }


}


async function open_tab(account  , line_num , mainpage ) {

    console.log(`  ---- > checking  ${account} `);
    let link = `https://example.com`;



    try {


        let user_password = account.split(':');


        if(!await mainpage.$('#username'))
        {
            console.log('...loading login page');
            await mainpage.goto(link , {timeout: 0});
            console.log('...done');

            if(await mainpage.$('.fatalerror'))
            {
                ACCOUNTSTACK.push(account);
                await mainpage.screenshot({path:  './fatalerror-a-'+line_num+'.jpg'  });
                return 'fatalerror';
            }

            console.log('...waitnign for login filds');

            await Promise.race([
                mainpage.waitForSelector('#username'),
                mainpage.waitForSelector('.fatalerror'),
            ]).catch(function (error) {
                throw new Error(error);
            });
            if(await mainpage.$('.fatalerror'))
            {
                ACCOUNTSTACK.push(account);
                await mainpage.screenshot({path:  './fatalerror-b-'+line_num+'.jpg'  });
                return 'fatalerror';
            }
            console.log('...done');



        }


        console.log('...typing user password');

        await mainpage.$eval('#username', (el ) => el.value = '' );
        await mainpage.$eval('#password', (el ) => el.value = '' );

        await mainpage.type('#username', user_password[0], {delay: 10})
        await mainpage.type('#password', user_password[1], {delay: 10})
        console.log('...done');

        console.log('...clicking login button');
        await mainpage.click('button.primary-button')

        await Promise.race([
            mainpage.waitForSelector('.theme-noticeerror-font'), // timeout
            mainpage.waitForSelector('.empty-inbox'), 
            mainpage.waitForSelector('.new-message'), 
            mainpage.waitForNavigation(),
        ]).catch(function (error) {
            throw new Error(error);
        });
        console.log('...done');

        if (await mainpage.$('.theme-noticeerror-font'))
        {
            console.log(account + '-- '+ line_num +' --> TIMEOUT')
            ACCOUNTSTACK.push(account);
            await mainpage.screenshot({path:  './timeout'+line_num+'.jpg'  });
            return 'fatalerror';

        }
        else if (await mainpage.$('.empty-inbox'))
        {
            console.log(account + '-- '+ line_num +' --> empty');
            wite_to_file('empty.txt' , account );

        }
        else if (await mainpage.$('.new-message'))
        {
            console.log(account + '-- '+ line_num +' --> new message')
            wite_to_file('newmsg.txt' , account );

        }



    }
    catch(e)
    {
        console.log(`--------ERRRO----${account}-${line_num}---------------------`);
        await mainpage.screenshot({path:  './images/error'+line_num+'.jpg'  });
        ACCOUNTSTACK.push(account);
        const html =  await mainpage.content();
        fs.writeFileSync('./images/error'+line_num+'.html', html);

    }
}


function wite_to_file( file , acc){

    fs.appendFile('./' + file ,   `${acc}\n` , function (err) {})

}

From time to time I get this error between my console.logs: 我不时在console.logs之间收到此错误:

(node:17535) MaxListenersExceededWarning: Possible EventEmitter memory leak dete       cted. 11 lifecycleevent listeners added to [FrameManager]. Use emitter.setMaxLis    teners() to increase limit
(node:17535) MaxListenersExceededWarning: Possible EventEmitter memory leak dete       cted. 11 framenavigatedwithindocument listeners added to [FrameManager]. Use emi    tter.setMaxListeners() to increase limit

I'm not sure what is causing this or whether it's serious or not? 我不确定是什么导致了这个或是否严重?

After running the code with --trace-warnings 使用--trace-warnings运行代码后

(node:992) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 framedetached listeners added to [FrameManager]. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:261:17)
    at FrameManager.addListener (events.js:277:10)
    at Function.addEventListener (/home/robot/node_modules/puppeteer/lib/helper.js:188:13)
    at new NavigatorWatcher (/home/robot/node_modules/puppeteer/lib/NavigatorWatcher.js:50:14)
    at Page.waitForNavigation (/home/robot/node_modules/puppeteer/lib/Page.js:618:21)
    at open_tab (/home/robot/psn.js:212:22)
    at processTicksAndRejections (internal/process/task_queues.js:85:5)
    at async init (/home/robot/psn.js:115:21)
(node:992) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 response listeners added to [NetworkManager]. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:261:17)
    at NetworkManager.addListener (events.js:277:10)
    at Function.addEventListener (/home/robot/node_modules/puppeteer/lib/helper.js:188:13)
    at Page.waitForNavigation (/home/robot/node_modules/puppeteer/lib/Page.js:621:29)
    at open_tab (/home/robot/psn.js:212:22)
    at processTicksAndRejections (internal/process/task_queues.js:85:5)
    at async init (/home/robot/psn.js:115:21)

This generally happens when too many ansync functions have been called without finishing. 当没有完成调用过多的ansync函数时,通常会发生这种情况。 And given that all async functions have a min timeout(0ms), they always get pushed to the end of the stack, and none of them will finish before a loop calling many of them. 并且鉴于所有异步函数都具有最小超时(0ms),它们总是被推到堆栈的末尾,并且它们都不会在循环调用其中许多之前完成。

Anyways, if you're trying to have tons of asynchronous events happen in parallel, 无论如何,如果你想要并行发生大量的异步事件,

disable it by setting the MaxListeners to 0 通过将MaxListeners设置为0来禁用它

process.setMaxListeners(0);

Alternatively, you can use for loops (not forEach), wrapped in an async function with awaits to make your code purely synchronous. 或者,你可以使用for循环(不是forEach),包含在异步函数中,等待使代码纯粹同步。 This can make logging nicer, if run time is no object. 如果运行时间不是对象,这可以使记录更好。

// example of de-parallelizing
(async () => {
  const userIds = await myDb.getAllUserIds();
  const usersWithoutFirstnames = [];

  for (userId of userIds) {
    console.log("Getting first name of user:", userId);
    const firstName = await myDb.getFirstName(userId);

    if (firstName) {
      console.log("SUCCESS: ", firstName);
    } else {
      console.log("First name not found");
      usersWithoutFirstnames.push(userId);
    }
  }
})(); // closures are back

I think the problem is related to these parts: 我认为问题与这些部分有关:

setInterval(function(){
  if(!inprogress)
    {
      init();
    }
}, 2000);
async function init(){

  ...

  browser._process.once('close', () => {
    console.log(' ------------------------  closed !');
    inprogress = false;
  });

  browser.on('disconnected', () => {
    console.log(' ------------------------  disconnecte !');
    inprogress = false;
  });

  ...

}

You trigger two event listeners every 2 seconds (if inprogress equals false ), but you only close these listeners when the process encounters fatalerror . 您每2秒触发两个事件侦听器(如果inprogress等于false ),但只有在进程遇到fatalerror时才关闭这些侦听fatalerror

if(check === 'fatalerror') {
  await browser.close();
}

So in the logic of your code, I think most of the close and disconnected listeners are still listening/waiting for the event happens, like the warnings you get, you may have more than 11 listeners at the same time. 因此,在您的代码逻辑中,我认为大多数closedisconnected侦听器仍在侦听/等待事件发生,就像您收到的警告一样,您可能同时拥有超过11个侦听器。 You should always make browser instance closed (unless you want to reuse the browser instance, seems it's not suited to your case because you have different ipport for every browser instance), and I think both these two event listeners could be consumed and release the memory properly. 你应该总是关闭browser实例(除非你想重用浏览器实例,看起来它不适合你的情况,因为你对每个浏览器实例都有不同的ipport ),我认为这两个事件监听器都可以被消费并释放内存正常。

So maybe you wanna always close browser like this: 所以也许你想要像这样关闭浏览器:

async function init(){
  ...
  while(inprogress) {
    ...  
  }
  await browser.close();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Discord.js 错误 - MaxListenersExceededWarning: 可能的 EventEmitter memory 检测到泄漏 - Discord.js Error - MaxListenersExceededWarning: Possible EventEmitter memory leak detected (节点:125008)MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏 - (node:125008) MaxListenersExceededWarning: Possible EventEmitter memory leak detected Electron-React:MaxListenersExceededWarning:检测到可能的 EventEmitter memory 泄漏。 21 个 updateDeviceList 监听器添加到 [EventEmitter] - Electron-React: MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 21 updateDeviceList listeners added to [EventEmitter] MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。 [Client] 添加了 11 个 voiceStateUpdate 监听器 - MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 voiceStateUpdate listeners added to [Client] MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。 添加了 11 个消息列表。 使用emitter.setMaxListeners() 增加限制 - MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message lis teners added. Use emitter.setMaxListeners() to increase limit (节点)警告:可能检测到EventEmitter内存泄漏 - (node) warning: possible EventEmitter memory leak detected WDIO 5:检测到可能的EventEmitter内存泄漏 - WDIO 5 : Possible EventEmitter memory leak detected Gulp + Watchify + Factor捆绑包“检测到可能的EventEmitter内存泄漏” - “Possible EventEmitter memory leak detected” with Gulp + Watchify + Factor bundle 检测到可能的 EventEmitter 内存泄漏。 Discord.js - Possible EventEmitter memory leak detected. Discord.js 安装 nodemon 时出错 - 检测到可能的 EventEmitter memory 泄漏 - Error installing nodemon - Possible EventEmitter memory leak detected
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM