大量JavaScript對象,我是新手,這樣的JavaScript的,所以我會給出一個簡要說明:刪除當進程運行內存
我有一個Web刮板內置Nodejs
它收集(相當一點點)數據,用Cheerio
(基本上jQuery
爲Node
)處理它創建一個對象,然後將其上傳到mongoDB。
它工作得很好,除了在較大的網站上。什麼是出現要發生的事情是:
- 我給刮板在線商店的網址刮
- 節點轉到該網址,隨時隨地獲取從5000 - 40000產品網址刮
- 對於每這些新的URL,Node的
request
模塊獲取頁面源,然後將數據加載到Cheerio
。 - 使用Cheerio我創建了一個代表產品的JS對象。
- 我將對象發送到MongoDB,並保存到我的數據庫。
正如我所說,這種情況發生在成千上萬的URL上,一旦我得到,比如說,加載了10,000個網址,我就會在節點中看到錯誤。最常見的是:
Node: Fatal JS Error: Process out of memory
好吧,這裏的實際問題(S):
我認爲這種情況正在發生,因爲節點的垃圾清理工作不正常。例如,有可能從所有40,000個URL中獲取的數據仍在內存中,或者至少有40,000個創建的JavaScript對象可能存在。也許這也是因爲MongoDB連接是在會話開始時進行的,並且從不關閉(我只是在完成所有產品後手動關閉腳本)。這是爲了避免每次登錄新產品時打開/關閉連接。
要真正確保它們被正確地清理(一旦產品進入MongoDB,我不再使用它並且可以從內存中刪除),我可以/只是簡單地使用delete product
從內存中刪除它?如果我刪除對象的一個引用是完全從內存中刪除的,還是我必須刪除所有這些對象?(我明顯不知道JS如何處理對象)?
例如:
var saveToDB = require ('./mongoDBFunction.js');
function getData(link){
request(link, function(data){
var $ = cheerio.load(data);
createProduct($)
})
}
function createProduct($)
var product = {
a: 'asadf',
b: 'asdfsd'
// there's about 50 lines of data in here in the real products but this is for brevity
}
product.name = $('.selector').dostuffwithitinjquery('etc');
saveToDB(product);
}
// In mongoDBFunction.js
exports.saveToDB(item){
db.products.save(item, function(err){
console.log("Item was successfully saved!");
delete item; // Will this completely delete the item from memory?
})
}
有趣。所以在上面的例子中,我需要''mongoDBFunction.js'中的變量以及主腳本發送到'saveToDB()'函數後'null?這是讓我困惑的對象的傳遞,試圖找出實際上有多少數據的「副本」。 – Jascination
只要你沒有在數組或類似的東西中累積數據引用,你通常不需要'null'。垃圾收集器(當給定週期運行時)將處理事情。除非DB或'cheerio'庫在內存中緩存或存儲內容,或者除非您將所有數據累積到自己的數組中,否則我猜測您可能需要手動運行GC。我會首先嚐試手動運行GC。如果這不起作用,那麼使用其中一個工具來顯示哪些對象正在使用內存。 – jfriend00
@Jascination - 還要記住,JavaScript通過引用傳遞數據(如數組和對象)和字符串(它不會因爲傳遞而傳遞它們的新副本)。 – jfriend00