4

Я написал небольшую программу, которая производит массивы, которая работает достаточно долго (почти вечно ;-)):памяти разреженных массивов в Node.js

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 занимает n раз пробел пустого массива с длиной 1.

Имею ли я право на это (в частности, на Node.js)? более

Один вопрос: Если я бегу

var results = []; 
var i = 1; 

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

тогда я получаю до 1286175, а затем снова падает с:

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

Почему это ведет себя иначе, чем две другие варианты?

PS: Я использую Node.js 0.12.0 запустить это на OS X.

+0

Я не вижу разреженного массива. Возможно, вы захотите удалить этот тег. – monocell

+0

Я обновил свой вопрос. –

ответ

6

Когда вы объявляете массив с размером

Array(1024); 

Вы делаете так, что он выделяет пространство для 1024 элемента. Он должен выделить это пространство вперед, потому что эта форма объявления массива - это оптимизация, указывающая

«Мне нужно, чтобы вы зарезервировали 1024 места, чтобы вы не постоянно изменяли размер массива, когда я нажимаю на него больше элементов ».

Как вы, вероятно, знаете, объявление массива с просто [] по-прежнему позволяет вам нажимать на него неограниченное количество элементов, однако массив не изменяется в размерах (скорее всего, memcpy()) за кулисами, чтобы это допускалось.

EDIT:

Причина вы получите гораздо выше итераций в вашем втором примере, это потому, что вы сейчас используете разреженный массив. При разреженном массиве

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

Не означает, что ваш массив теперь использует 1 000 000 записей в памяти. Сравните это с плотным массивом

var arr = Array(1000000); 

Что явно говорит о времени выполнения для резервирования массива, который может хранить записи в 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

Мой ответ по-прежнему верен? :) –

Смежные вопросы