11-03-25 18:24:04
Когда мы создаем переменные, объекты или функции, они занимают память в оперативной памяти. В JavaScript процесс управления памятью состоит из трех этапов:
Пример создания и использования объектов:
let user = {
name: "Alex",
age: 30
};
// Используем объект
console.log(user.name); // "Alex"
// Теперь объект больше не нужен
user = null; // Помечен для удаления сборщиком мусора
После того как переменная user установлена в null, объект { name: "Alex", age: 30 } становится недоступным и сборщик мусора его удалит.
Счетчик ссылок (Reference Counting)
Этот метод отслеживает количество ссылок на объект. Когда счетчик ссылок становится равен нулю, объект удаляется.
let obj1 = { name: "John" };
let obj2 = obj1; // obj2 ссылается на obj1
obj1 = null; // obj2 всё ещё ссылается на объект, поэтому он не удаляется
obj2 = null; // Теперь объект больше не имеет ссылок и будет удалён
Принцип достижимости (Mark-and-Sweep)
Этот алгоритм используется в современных движках JavaScript (V8, SpiderMonkey, Chakra). Он определяет "достижимые" объекты и удаляет те, к которым нельзя добраться.
function createObject() {
let obj = { data: "some data" };
return obj;
}
let ref = createObject(); // объект сохранен в переменной ref
ref = null; // объект становится недоступным и будет удалён GC
Забытая ссылка
Если объект остается в памяти из-за ненужных ссылок, он не удаляется.
let user = {
name: "Alice"
};
let ref = user; // Вторая ссылка на объект
user = null; // Объект все еще доступен через ref
Решение: устанавливать ref = null, когда объект больше не нужен.
Замыкания
Функции в JavaScript создают замыкания, которые могут привести к утечке памяти.
function createClosure() {
let bigArray = new Array(1000000).fill("data");
return function () {
console.log(bigArray.length);
};
}
let closure = createClosure();
// bigArray остаётся в памяти из-за замыкания
Решение: устанавливать bigArray = null внутри функции при ненадобности.
Утечки в DOM
Если элемент удаляется из DOM, но на него остались ссылки в коде, он не будет очищен.
let button = document.createElement("button");
button.innerText = "Click me";
document.body.appendChild(button);
let reference = button;
document.body.removeChild(button); // Элемент удалён из DOM, но всё ещё доступен через reference
Решение: после удаления элемента из DOM устанавливать reference = null.
1. Используйте let и const вместо var – так переменные живут только в своей области видимости.
2. Явно обнуляйте ненужные ссылки:
let obj = { data: "value" };
obj = null; // Объект освобождается
3. Избегайте хранения больших объектов в замыканиях.
4. Очищайте обработчики событий, если элемент больше не используется:
function onClick() {
console.log("Clicked");
}
let button = document.getElementById("myButton");
button.addEventListener("click", onClick);
// Удаляем обработчик при ненадобности
button.removeEventListener("click", onClick);
5. Используйте WeakMap и WeakSet для временных данных:
let weakMap = new WeakMap();
let obj = { name: "Alice" };
weakMap.set(obj, "data");
obj = null; // Объект будет автоматически удалён
Сборщик мусора автоматически очищает память, удаляя неиспользуемые объекты. Однако неправильное управление ссылками может приводить к утечкам памяти. Чтобы избежать проблем, важно следить за замыканиями, DOM-элементами и использовать слабые коллекции (WeakMap, WeakSet).