一段内存泄漏的nodejs代码,你能看出哪里的问题吗?
发布于 3 年前 作者 liupanjjjj 1585 次浏览 来自 问答
var http=require("http");
var puppeteer = require("puppeteer");
var fs = require('fs')
var path = require("path")
const url = require('url');
require('events').EventEmitter.defaultMaxListeners = 50;
console.log("server starting!") ;
console.log("init puppeteer browser!") ;
const MAX_WSE = 5;  //启动几个浏览器
const WSE_LIST = []; //存储browserWSEndpoint列表
init();
console.log("init puppeteer browser success!") ;
http.createServer(function (req,res){
    let tmp = Math.floor(Math.random()* MAX_WSE);
    var page = null;
    var myProcess = (async () => {
        let browserWSEndpoint = WSE_LIST[tmp];
        //console.log("brower "+tmp+" begin process!")
        const browser = await puppeteer.connect({browserWSEndpoint});
        const path = url.parse(req.url,true).query;

        const target = path.target;
        const filePath = path.filePath;
        const fileName = path.fileName;

        page = await browser.newPage();
        await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36');
        await page.setViewport({width: 1640,height:0});

        await page.goto(target, {
            waitUntil: 'networkidle2',
        });
        let pageHeight = await page.evaluate(() => {
            return Promise.resolve(window.document.body.scrollHeight);
        });

        await page.setViewport({width: 1640, height: pageHeight});
        await page.evaluate(() => {
            return Promise.resolve(window.scrollTo(0,document.body.scrollHeight));
        });

        await page.waitForTimeout(1000);
        await dirExists(filePath);
        await page.screenshot({path: (filePath+fileName),fullPage:true});
        await page.close();
        res.writeHead(200, {'Content-Type': 'application/json; charset=utf-8'});
        res.write("{success:true}");
        res.end();
    });
    myProcess().catch(()=>{
        res.writeHead(200, {'Content-Type': 'application/json; charset=utf-8'});
        res.write("{success:false}");
        res.end();
        page && page.close();
    });
}).listen(3000);
console.log("server start success!listen on port 3000") ;



function init(){
    (async () => {
        for(var i=0;i<MAX_WSE;i++){
            const browser = await puppeteer.launch({headless:true,
                args: [
                    '--disable-gpu',
                    '--disable-dev-shm-usage',
                    '--disable-setuid-sandbox',
                    '--no-first-run',
                    '--no-sandbox',
                    '--no-zygote',
                    '--single-process'
                ]});
            browserWSEndpoint = await browser.wsEndpoint();
            WSE_LIST[i] = browserWSEndpoint;
        }
        console.log(WSE_LIST);
    })();
}

/**
 * 读取路径信息
 * @param {string} path 路径
 */
function getStat(path){
    return new Promise((resolve, reject) => {
        fs.stat(path, (err, stats) => {
            if(err){
                resolve(false);
            }else{
                resolve(stats);
            }
        })
    })
}

/**
 * 创建路径
 * @param {string} dir 路径
 */
function mkdir(dir){
    return new Promise((resolve, reject) => {
        fs.mkdir(dir, err => {
            if(err){
                resolve(false);
            }else{
                resolve(true);
            }
        })
    })
}

/**
 * 路径是否存在,不存在则创建
 * @param {string} dir 路径
 */
async function dirExists(dir){
    let isExists = await getStat(dir);
    //如果该路径且不是文件,返回true
    if(isExists && isExists.isDirectory()){
        return true;
    }else if(isExists){     //如果该路径存在但是文件,返回false
        return false;
    }
    //如果该路径不存在
    let tempDir = path.parse(dir).dir;      //拿到上级路径
    //递归判断,如果上级目录也不存在,则会代码会在此处继续循环执行,直到目录存在
    let status = await dirExists(tempDir);
    let mkdirStatus;
    if(status){
        mkdirStatus = await mkdir(dir);
    }
    return mkdirStatus;
}


2 回复

@zengming00 page释放了browser 没释放

回到顶部