2016-08-22 4 views
1

У меня есть сцена использования массива как очереди, и у меня есть вопрос об этой сцене о памяти.Управление памятью массива Javascript/Node.js

Во-первых, я создаю объект массива в глобальном масштабе и создаю продюсера, чтобы заставить элемент массива работать без прерывания.

var arr = []; 

function runningProducer() { 
    setInterval(itemProducer, 50); 

    function itemProducer() { 
    var item = generateItem(); 
    arr.push(item); 
    } 
    function generateItem() { 
    return { a: Math.random(), }; 
    } 
} 

Затем я создаю клиент, чтобы очистить массив в 1 второго

function runningCustomer() { 
    setInterval(clearQueue, 1000); 

    function clearQueue() { 
    var t = arr.concat(arr); 
    arr = []; 
    } 
} 

и выполнение вышеуказанных функций в течение периода времени, я обнаружил, что память всегда растет.

setInterval(() => { 
    var mem = process.memoryUsage(); 
    console.log(mem); 
}, 2000); 

Я думаю, что массив должен освободить память после пустого набора, но нет. Пожалуйста, дайте мне несколько советов по этому вопросу, и есть ли способ освободить память вручную в javascript?

+4

Память будет очищена при запуске сборщика мусора, а не сразу, когда вы очистите массив. – Barmar

+1

Что такое 'var t = arr.concat (arr),' предполагается делать? Если переменная 't' не упоминается в другом месте, то вся строка является избыточной, но если она * указана в другом месте (каким-то образом, в коде не показана), то ссылка на этот массив (которая вдвое больше размера' arr' была) все еще существует, поэтому он будет продолжать использовать память. – nnnnnn

+1

Производитель использует массив, вы не можете ожидать, что массив будет очищен из памяти. –

ответ

3

Ответ на этот вопрос содержится в комментарии Бармара. Зарезервированная память не будет немедленно выпущена в тот момент, когда она больше не нужна. JavaScript полагается на сборку мусора, чтобы обнаружить неиспользуемые ссылки и отпустить их обратно в кучу, но сбор мусора - дорогостоящая процедура, поэтому она запускается только раз в то время.

Когда я пытаюсь запустить код, использование памяти увеличивается в течение минуты или двух, а затем внезапно возвращается к исходному значению, когда выполняется сбор мусора. Возможно, вы просто недостаточно долго смотрели журнал?

Вы можете вручную запустить сборку мусора и увидеть это для себя, запустив узел с --expose-gc флагом и выполнения global.gc() но вы должны не сделать это в рабочем коде, если у вас есть очень веские основания.

+0

Есть небольшая проблема, я нашел, что память использования вернется к исходной памяти, но она будет немного больше, чем оригинал, около 10 КБ. каждый раз, когда это так. – kenticny

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