Что такое Утечки Памяти?
Утечки памяти происходят когда приложения выделяют память но не освобождают её, вызывая рост потребления памяти до истощения системных ресурсов.
Частые Симптомы
- Увеличение использования памяти со временем
- Замедление приложения после длительного использования
- Ошибки Out of Memory (OOM)
- Паузы сборки мусора
- Нестабильность системы
Утечки Памяти JavaScript
1. Отсоединенные DOM Узлы
// Утечка памяти - отсоединенные DOM узлы
let elements = [];
function createElements() {
for (let i = 0; i < 1000; i++) {
let div = document.createElement('div');
elements.push(div); // Сохранено но не присоединено
}
}
// Исправлено
const container = document.getElementById('container');
for (let i = 0; i < 1000; i++) {
container.appendChild(document.createElement('div'));
}
elements = []; // Очистить ссылки
2. Event Listeners
// Утечка - listeners не удалены
function setupButton() {
const button = document.getElementById('myButton');
button.addEventListener('click', function heavyHandler() {
const largeData = new Array(1000000).fill('data');
});
}
// Исправлено - удалить listeners
function setupButtonFixed() {
const button = document.getElementById('myButton');
const handler = () => { /* ... */ };
button.addEventListener('click', handler);
return () => button.removeEventListener('click', handler);
}
Browser DevTools
Chrome DevTools
// 1. Сделать heap snapshot
// DevTools → Memory → Heap snapshot → Take snapshot
// 2. Сравнить snapshots
// Snapshot 1: Начальное состояние
// Выполнить действия
// Snapshot 2: После действий
// Сравнить для поиска удерживаемых объектов
Node.js Обнаружение Утечек
# Использовать clinic
npm install -g clinic
clinic doctor -- node app.js
# Генерировать нагрузку
ab -n 10000 -c 100 http://localhost:3000/
Автоматизированное Тестирование
// Puppeteer memory testing
const puppeteer = require('puppeteer');
async function testMemoryLeaks() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const measurements = [];
for (let i = 0; i < 50; i++) {
await page.click('#button');
const memory = await page.evaluate(() =>
performance.memory.usedJSHeapSize
);
measurements.push(memory);
}
const growth = measurements[49] - measurements[0];
if (growth > 50 * 1024 * 1024) {
console.error('Обнаружена утечка памяти!');
}
await browser.close();
}
Лучшие Практики
- [ ] Удалять event listeners при очистке
- [ ] Очищать все intervals/timeouts
- [ ] Использовать WeakMap для кэширования
- [ ] Очищать отсоединенные DOM узлы
- [ ] Реализовать лимиты размера кэшей
Заключение
Обнаружение утечек памяти критично для стабильности и производительности. Использование подходящих инструментов, реализация автоматизированных тестов и следование лучшим практикам предотвращает утечки до того как они затронут пользователей.