2013-01-16 2 views
0

У меня есть очень большая коллекция объектов в node.js (в миллионах), которые мне нужно хранить в памяти для кеширования (они поддерживаются в нескольких глобальных хэш-объектах). Каждая коллекция хешей хранит около 750 тыс. Ключей.Будет ли постоянная коллекция проверяться во время сбора мусора?

Чтобы свести GC к минимуму, я хочу найти лучший способ хранения этих предметов. Было бы лучше разделить эти предметы на 100 тысяч тысяч хэшей? Должен ли я вообще не использовать хеши? Есть ли способ полностью отключить их от кучи, чтобы они никогда не проверялись GC (и если да, то как мне это сделать)?

ответ

2

Нет публичного API для управления сборкой мусора из JavaScript.

Но GC прошел долгий путь на протяжении многих лет. Современные реализации GC заметят, что некоторые объекты живут долго и помещают их в специальную «область», которая будет собираться только редко.

Как это точно работает, полностью зависит от реализации; каждый браузер делает это самостоятельно, и обычно это также часто изменяется при выпуске новой версии браузера.

EDIT Макет по памяти и организации совершенно не имеет значения. Современные GC действительно трудно понять подробно, не вкладывая пару недель в чтение фактического кода. Так что я объясняю сейчас, это действительно упрощенная картина; реальный код будет работать по-другому (и некоторые GC будут использовать совершенно разные трюки для достижения той же цели).

Представьте, что GC имеет счетчик для каждого объекта, в котором он подсчитывает, как часто он видел его в прошлом. Кроме того, в нем есть несколько списков, в которых хранятся объекты разного возраста, то есть объекты, чьи счетчики прошли определенные пороговые значения. Поэтому, когда счетчик достигает некоторого предела, объект перемещается в следующий список.

Первый список посещается каждый раз, когда GC запускается. Второй список рассматривается только для каждого N-го цикла GC.

Альтернативная реализация может добавлять новые объекты в верхнюю часть «списка GC» и для каждого запуска GC она проверяет только N элементов. Длинные живые объекты будут двигаться вниз по списку, и через некоторое время они не будут проверяться каждый раз.

Это означает, что вам не нужно ничего делать; GC выяснит, что ваша огромная карта живет долго (и то же самое верно для всех объектов на карте), и через некоторое время она начнет игнорировать эту структуру данных.

+0

Мне действительно интересно, как это реализовано в node.js, но я предполагаю, что это то же самое, поскольку он использует v8. Когда вы говорите, что собраны редко, что это значит? Например, если у меня есть хэш с 10 000 000 ключей, если он может сказать, что хеш не должен быть GC'd, он все равно будет опускаться и проверять каждый отдельный ключ в хэше? Если он рассмотрит каждый ключ, лучше ли иметь 100 хешей, каждый из которых содержит 100 000 предметов вместо одного большого хеша? Это имеет значение? Просто пытаюсь выяснить, как избежать GC в этой коллекции. – AlexGad

+1

Я нашел интересное обсуждение в группе node.js https://groups.google.com/forum/?fromgroups=#!topic/nodejs/BO6JdYi4n2k. Кажется, что V8 не выполняет раздельное сканирование больших объектов, поэтому он будет перемещать весь объект. Если я разбиваю свои объекты на многие более мелкие объекты, тогда произойдет раздельное сканирование, что значительно снижает вероятность того, что GC внезапно остановит все, чтобы пройти миллион объектов объекта. Кто-то замечает, что лучше разместить вещи вне кучи. Как это будет достигнуто? Через внешний код c? – AlexGad

+0

@AlexGad: Конечно, но следующая версия v8 может сделать это совершенно иначе. Вопрос: Является ли ваша цель [преждевременная оптимизация] (http://c2.com/cgi/wiki?PrematureOptimization) или у вас действительно есть проблема, которую вы исправили? –

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