2015-04-23 211 views
4

我已經寫一個小程序,產生陣列,它運行相當長的(幾乎永遠;-)):代替空數組內存消耗

var results = []; 
var i = 1; 

while (true) { 
    console.log(i++); 
    results.push([]); 
} 

當,我創建長度爲i的稀疏陣列,該程序崩潰相當快:

var results = []; 
var i = 1; 

while (true) { 
    console.log(i); 
    results.push(new Array(i++)); 
} 

其實我起牀i等於17424,然後我得到一個錯誤信息,告訴我

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory 
Abort trap: 6 

和Node.js帶我回到控制檯。由於唯一的區別是第二個產生比第一個更大的空數組,所以這意味着長度爲n的空稀疏數組佔用空數組的長度爲1的空間的n倍。

我是對的嗎(具體到Node.js)?

一個問題:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory 
Abort trap: 6 

爲什麼會出現這種行爲比其他兩個選項是不同的:如果我運行

var results = []; 
var i = 1; 

while (true) { 
    console.log(i); 
    var temp = []; 
    temp[i++] = i; 
    results.push(temp); 
} 

然後我起牀到1286175,然後再次崩潰?

PS:我使用Node.js的0.12.0到在OS X上運行此

+0

我無法看到稀疏陣列。您可能想要移除該標籤。 – monocell

+0

我已更新我的問題。 –

回答

6

在聲明數組的大小

Array(1024); 

你這樣做,它的分配空間1024個元素。它必須預先分配這個空間,因爲這種聲明陣列的形式是一個優化,它說明了一個優化,它說明了我需要你保留1024個位置,這樣當我將更多的元素推到它上面時,你不會不斷調整數組的大小」。你可能知道,聲明一個簡單的[]數組仍然允許你將無限數量的元素放到它上面,但是這個數組默默地在幕後調整大小(很可能是memcpy())以允許這種行爲。

編輯:

你在第二個例子中得到更高的迭代究其原因,是因爲你現在使用的是稀疏數組。用一個稀疏陣列做

var arr = [] 
arr[1000000] = 1; 

並不意味着你的數組現在在內存中使用了1,000,000個條目。與此不同,密集排列

var arr = Array(1000000); 

其中明確告知運行時保留,可以在內存中存儲的條目百萬的數組。

相關的StackOverflow問題:https://stackoverflow.com/a/1510842/276949

+0

好的。感謝這:-) –

+0

我更新了我的問題。 –

+0

確定,更新回答 –

4

V8,在節點JS引擎,使用每個元件的4個字節在一個看似空數組。找出這一點的最好方法是在Chrome中創建空數組,然後使用分析器查看陣列已經用盡了多少額外的大小。有關如何執行此操作的詳細信息,請參閱https://developer.chrome.com/devtools/docs/heap-profiling ...

+0

我更新了我的問題。 –

+0

我的回答仍然正確嗎? :) –