Ответ 1
Как работает сбор мусора?
Короткий ответ: когда блок памяти (объект, скажем) больше недоступен, он может быть исправлен. Когда, как, или он исправляется, полностью зависит от реализации, а разные реализации делают это по-другому. Но на уровне языка он автоматически.
Например:
function foo() {
var bar;
bar = new ReallyMassiveObject();
bar.someCall();
}
Когда foo
возвращается, объект bar
указывает, что он автоматически доступен для сбора мусора, потому что ничего не осталось, что имеет ссылку на него.
Контраст с:
function foo() {
var bar;
bar = new ReallyMassiveObject();
bar.someCall();
return bar;
}
// elsewhere
var b = foo();
... теперь ссылка на объект выдержала вызов и сохраняется до/если вызывающий абонент не присваивает что-то еще b
или b
выходит за пределы области видимости.
Также контрастирует с:
function foo() {
var bar;
bar = new ReallyMassiveObject();
bar.someCall();
setTimeout(function() {
alert("Three seconds have passed");
}, 3000);
}
Здесь, даже после возврата foo
, механизм таймера имеет ссылку на обратный вызов таймера и обратный вызов таймера — закрытие — имеет ссылку на контекст, где он был создан, который, в свою очередь, содержит переменную bar
. В результате теоретически, что означает bar
, недоступно для сбора мусора сразу же, когда возвращается foo
. Вместо этого он сохранялся до тех пор, пока таймер не срабатывает и не освобождает ссылку на обратный вызов, делая обратный вызов и контекст, который он ссылается на право на GC. (На практике современные механизмы JavaScript могут и могут оптимизировать закрытие, где они могут. Например, в приведенном выше статическом анализе показано, что обратный вызов не относится к bar
и не содержит никаких eval
или new Function
код, который может ссылаться на него динамически во время выполнения, поэтому механизм JavaScript может спокойно покинуть bar
из контекста, на который ссылается функция, тем самым делая то, что он имеет в виду для GC — и современные). (Подробнее о закрытии в в этой статье.)
JavaScript не имеет проблем с обработкой очистки круговых ссылок, к примеру, например:
function foo() {
var a, b;
a = {};
b = {};
b.refa = a;
a.refb = b;
}
Когда foo
возвращается, факт, что a
относится к b
и наоборот, не является проблемой. Поскольку ничто другое не относится ни к одному из них, они могут очищаться. В IE это не true, если один из объектов является объектом, предоставленным хостом (например, элементом DOM или чем-то, созданным с помощью new ActiveXObject
) вместо объекта JavaScript. (Например, если вы помещаете ссылку на объект JavaScript на элемент DOM, а объект JavaScript ссылается на элемент DOM, они сохраняют друг друга в памяти, даже если никто не ссылается ни на один из них.) Но что IE ошибка, а не вещь JavaScript.
Re:
это потому, что vbscript GC плох, что люди вернулись к javascript в качестве своей стандартной клиентской стороны api?
JavaScript был оригинальным клиентским веб-скриптовым языком. VBScript появился только позже, когда Microsoft вышла с браузером и поддерживалась только в браузерах Microsoft. JavaScript был и остается единственной клиентской скриптовой игрой в городе, если вы хотите работать с самым широким диапазоном браузеров. <subjective> Это также примерно в восемь раз больше классического языка VBScript.;-) </subjective>