Управление памятью

Архитектурная модель распределения памяти

В основе работы Deck.gl лежит WebGL-контекст, в котором ресурсы делятся на несколько ключевых категорий: буферы атрибутов, индексные буферы, текстуры, фреймбуферы и внутренние состояния шейдеров. Управление памятью в этой среде определяется не только созданием и удалением объектов, но и стратегиями повторного использования GPU-ресурсов.

Каждый слой (layer) в Deck.gl выступает как независимая единица, инкапсулирующая набор WebGL-ресурсов. При этом жизненный цикл слоя напрямую связан с выделением и освобождением памяти, а некорректное управление приводит к утечкам GPU-памяти и деградации производительности.


Жизненный цикл слоёв и влияние на память

Создание слоя инициирует подготовку структуры данных, однако реальные GPU-ресурсы выделяются лениво — только при первом рендере или обновлении атрибутов.

Ключевые этапы:

  • инициализация слоя и его props;
  • подготовка attribute manager;
  • создание буферов при первом вычислении геометрии;
  • привязка шейдерных программ;
  • последующее переиспользование ресурсов при обновлениях.

Удаление слоя не всегда означает немедленное освобождение памяти. WebGL-ресурсы могут оставаться в контексте до тех пор, пока не произойдёт явный вызов финализации или сборка контекста.


Буферы атрибутов и их переиспользование

Основной потребитель памяти в Deck.gl — VertexBuffer и AttributeManager. Каждый атрибут геометрии (позиции, цвета, нормали, индексы) хранится в виде TypedArray и синхронизируется с GPU.

Оптимизация достигается через:

  • переиспользование буферов между обновлениями данных;
  • частичное обновление атрибутов вместо полного пересоздания;
  • использование инстансинга для повторяющихся геометрий;
  • минимизацию числа атрибутов в шейдерах.

Особое значение имеет стратегия обновления атрибутов через updateTriggers, которая позволяет избегать лишних пересчётов и пересоздания буферов.


TypedArray как промежуточный слой памяти

Deck.gl активно использует структуры Float32Array, Uint8Array, Uint16Array для хранения геометрических данных до их передачи в GPU.

Важные аспекты:

  • данные часто хранятся в плоском бинарном формате;
  • избегается промежуточная JSON-сериализация;
  • уменьшается давление на GC (garbage collector);
  • обеспечивается предсказуемый layout памяти.

Конвертация данных в TypedArray является одной из ключевых точек контроля потребления памяти на CPU-стороне.


Управление текстурами

Текстуры в Deck.gl используются в слоях типа TileLayer, BitmapLayer, IconLayer и других визуальных примитивах, зависящих от изображений.

Особенности управления памятью текстур:

  • загрузка изображений часто асинхронна;
  • кэширование текстур снижает количество повторных загрузок;
  • mipmapping увеличивает потребление GPU-памяти;
  • размер текстуры напрямую влияет на нагрузку видеопамяти.

При работе с тайловыми слоями важную роль играет механизм дедупликации: одинаковые тайлы не создают новые текстуры, а используют уже загруженные ресурсы.


Кэширование геометрии и данных

Deck.gl применяет многоуровневое кэширование:

  • кэш вычисленных атрибутов;
  • кэш геометрии в слоях типа PathLayer и PolygonLayer;
  • кэш загруженных данных в loaders.gl;
  • кэш тайлов в TileLayer.

Кэширование уменьшает количество перерасчётов, но увеличивает использование памяти. Баланс достигается через TTL-подобные стратегии и ограничение размера кэша.

Особенно критично поведение кэша при динамических данных, где обновления происходят часто и непредсказуемо.


Инстансинг и экономия GPU-памяти

Instanced rendering является одним из ключевых механизмов оптимизации памяти. Вместо создания отдельных геометрий для каждого объекта используется базовая модель и набор инстанс-атрибутов.

Преимущества:

  • сокращение объёма vertex buffer;
  • уменьшение количества draw calls;
  • эффективное использование cache locality на GPU;
  • снижение нагрузки на драйвер WebGL.

В слоях типа ScatterplotLayer и IconLayer инстансинг является основным механизмом масштабирования больших наборов данных.


Обновление данных и частичная пересборка буферов

При изменении props слоя Deck.gl избегает полного пересоздания GPU-ресурсов. Вместо этого применяется дифференциальное обновление.

Механизмы:

  • сравнение старых и новых данных;
  • пересоздание только изменённых атрибутов;
  • сохранение неизменённых буферов;
  • использование attribute.update() вместо полной регенерации.

Ключевым элементом является система dirty flag, которая определяет, какие части слоя требуют пересчёта.


Утечки памяти и типовые причины

Наиболее распространённые источники утечек:

  • сохранение ссылок на WebGLBuffer вне жизненного цикла слоя;
  • отсутствие вызова финализации контекста;
  • накопление текстур в кэше без ограничения размера;
  • частые пересоздания слоёв без переиспользования;
  • некорректная работа с анонимными функциями в атрибутах.

Особое внимание требуется при работе с динамическими сценами, где слои создаются и удаляются на каждом кадре.


Финализация ресурсов WebGL

Освобождение памяти в Deck.gl связано с явным разрушением WebGL-ресурсов:

  • удаление буферов через gl.deleteBuffer;
  • освобождение текстур через gl.deleteTexture;
  • очистка шейдерных программ;
  • разрыв связей между слоями и контекстом.

Процесс финализации часто происходит асинхронно относительно логики приложения, что требует аккуратного контроля жизненного цикла объектов.


Влияние view state на потребление памяти

Изменение состояния камеры (viewState) влияет на количество активных ресурсов, особенно в слоях с уровневой детализацией.

LOD-механизмы приводят к:

  • загрузке дополнительных геометрий при приближении;
  • выгрузке данных при удалении от сцены;
  • динамическому созданию и уничтожению тайлов;
  • перерасчёту атрибутов в зависимости от масштаба.

Управление памятью в Tile-based слоях

TileLayer и аналогичные структуры используют пространственное разбиение данных.

Характерные особенности:

  • активны только видимые тайлы;
  • вне области видимости тайлы выгружаются;
  • применяется LRU-кэширование;
  • загрузка данных происходит по мере необходимости.

Основная сложность заключается в балансировке между плавностью визуализации и ограничением памяти при больших геоданных.


Оптимизация использования GPU через ограничение ресурсов

Контроль памяти достигается через системные ограничения:

  • лимитирование размера кэша текстур;
  • ограничение количества одновременно активных слоёв;
  • управление resolution scale;
  • отключение ненужных визуальных эффектов (shadows, postprocessing).

Снижение качества визуализации часто приводит к линейному уменьшению потребления GPU-памяти.


Связь AttributeManager и распределения памяти

AttributeManager выступает центральным компонентом контроля буферов. Он:

  • определяет структуру атрибутов;
  • управляет их пересчётом;
  • контролирует синхронизацию CPU ↔︎ GPU;
  • минимизирует избыточные обновления.

Эффективность работы AttributeManager напрямую определяет стабильность использования памяти в сложных сценах с тысячами объектов.