Object Pool Pattern — Пул объектов

Заранее создать N инстансов, переиспользовать их вместо создания/уничтожения. Не входит в каноническую GoF, но критичен для производительности.

Проблема

Создание объекта дорогое: коннект к БД, открытие сокета, выделение буфера. Если объекты нужны часто, но кратко (короткая операция → закрыть → не нужен) — создание/освобождение становятся узким местом.

Дополнительно: нужно ограничить число одновременных ресурсоёмких объектов (например, не более 25 параллельных соединений).

Решение

Лестница абстракций по автору: instance → class → factory → pool.

  • При старте создать N объектов в пуле
  • acquire — взять свободный (или создать новый, если есть лимит)
  • release(obj) — вернуть в пул после использования (без уничтожения)
  • Опционально — reset объекта перед возвратом в пул

Пример в JS

class Pool {
  constructor(factory, size = 10) {
    this.free = Array.from({ length: size }, factory);
    this.factory = factory;
  }

  acquire {
    return this.free.pop() ?? this.factory;
  }

  release(item) {
    if (typeof item.reset() === 'function') item.reset();
    this.free.push(item);
  }
}

// пример: пул буферов
const buffers = new Pool( => Buffer.alloc(1024), 100);
const buf = buffers.acquire;
// ... используем
buffers.release(buf);

Где используется в JS-экосистеме

  • pg-pool, mysql2.createPool — пулы соединений к БД
  • generic-pool (npm) — универсальный пул
  • worker_threads pool — пул воркеров под нагрузку
  • Node.js Stream Buffer — внутренний пул

Подводные камни

  • Состояние объекта не сбрасывается автоматически — нужно явно вызвать reset перед release.
  • Утечки: если забыть release, пул исчерпается и приложение зависнет.
  • Слишком большой пул = жрёт память; слишком маленький = bottleneck.
  • В JS GC и без пула быстро освобождает мелкие объекты — пул нужен для дорогих ресурсов.

Главные тезисы автора

  • «Пул сразу инстанцирует много и потом выдаёт по несколько» — основная идея.
  • Используется для ограничения числа ресурсоёмких копий: таймеры, сокеты, дескрипторы.
  • poolify — обобщённый оператор: превращает любой класс в пул.
  • Стоит выше фабрики в лестнице абстракций.
  • Часть стандартных синглтонов (DB pool) — на самом деле пулы.

🎓 Источники

См. также