防止Javascript函数因对象太多而内存不足

防止Javascript函数因对象太多而内存不足,javascript,performance,node.js,memory,Javascript,Performance,Node.js,Memory,我正在nodeJS中构建一个web scraper,它使用request和cheerio解析DOM。当我使用node时,我认为这更像是一个一般的javascript问题 tl;dr-创建约60000-100000个对象,耗尽我计算机的所有RAM,在节点中出现内存不足错误。 这是铲运机的工作原理。这是循环中的循环,我以前从未设计过如此复杂的东西,所以可能有更好的方法来实现这一点 循环1:在名为“sitesArr”的数组中创建10个对象。每个对象代表一个要刮取的网站 var sitesArr = [

我正在
nodeJS
中构建一个web scraper,它使用
request
cheerio
解析DOM。当我使用
node
时,我认为这更像是一个一般的
javascript
问题

tl;dr-创建约60000-100000个对象,耗尽我计算机的所有RAM,在节点中出现
内存不足
错误。

这是铲运机的工作原理。这是循环中的循环,我以前从未设计过如此复杂的东西,所以可能有更好的方法来实现这一点

循环1:在名为“sitesArr”的数组中创建10个对象。每个对象代表一个要刮取的网站

var sitesArr = [
    {
        name: 'store name',
        baseURL: 'www.basedomain.com',
        categoryFunct: '(function(){ // do stuff })();',
        gender: 'mens', 
        currency: 'USD',
        title_selector: 'h1',
        description_selector: 'p.description'
    },
    // ... x10
]
循环2:通过“sitesArr”循环。对于每个站点,它通过“请求”进入主页,并获得类别链接列表,通常为30-70个URL。将这些URL附加到名称为“categories”的数组属性中它们所属的当前“sitesArr”对象

var sitesArr = [
    {
        name: 'store name',
        baseURL: 'www.basedomain.com',
        categoryFunct: '(function(){ // do stuff })();',
        gender: 'mens', 
        currency: 'USD',
        title_selector: 'h1',
        description_selector: 'p.description',
        categories: [
                        {
                            name: 'shoes',
                            url: 'www.basedomain.com/shoes'
                        },{
                            name: 'socks',
                            url: 'www.basedomain.com/socks'
                        } // x 50
                    ]
    },
    // ... x10
]
循环3:循环每个“类别”。对于每个URL,它都会获得一个产品链接列表,并将它们放入一个数组中。通常每类约300-1000种产品

var sitesArr = [
    {
        name: 'store name',
        baseURL: 'www.basedomain.com',
        categoryFunct: '(function(){ // do stuff })();',
        gender: 'mens', 
        currency: 'USD',
        title_selector: 'h1',
        description_selector: 'p.description',
        categories: [
                        {
                            name: 'shoes',
                            url: 'www.basedomain.com/shoes',
                            products: [
                                'www.basedomain.com/shoes/product1.html',
                                'www.basedomain.com/shoes/product2.html',
                                'www.basedomain.com/shoes/product3.html',
                                // x 300
                            ]
                        },// x 50
                    ]
    },
    // ... x10
]
循环4:循环每个“产品”数组,转到每个URL并为每个URL创建一个对象

var product = {
    infoLink: "www.basedomain.com/shoes/product1.html",
    description: "This is a description for the object",
    title: "Product 1",
    Category: "Shoes",
    imgs: ['http://foo.com/img.jpg','http://foo.com/img2.jpg','http://foo.com/img3.jpg'],
    price: 60,
    currency: 'USD'
}
然后,对于每个产品对象,我将它们发送到一个MongoDB函数,该函数将
上传到我的数据库中

问题

这一切都很好,直到过程变得更大。每次运行这个脚本时,我都会创建大约60000个产品对象,过了一会儿,我的计算机的所有RAM都被用完了。更重要的是,在完成了大约一半的过程后,我在
节点中得到了以下错误:

 FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory

我认为这是一个代码设计问题。我应该在处理完对象后“删除”它们吗?解决这个问题的最佳方法是什么?

似乎“有一种比循环中的循环更好的方法”,例如,您应该使用队列,并可以生成进程来处理其他内容。因为铲运机会吃掉你的公羊,所以与其买更多的公羊,不如试试“有更好的方法”approach@GeoPhoenix你能推荐一些学习这方面的资源吗?我不熟悉基本网站之外的编码,所以不知道从哪里开始。我认为在使用大型对象后,应该将其设置为null,以释放此答案中给出的内存