CesiumJS работает поверх WebGL, где управление памятью разделено между двумя уровнями: JavaScript-heap и GPU-memory. Сборщик мусора V8 управляет только объектами JavaScript, тогда как текстуры, буферы вершин, индексные буферы и шейдерные программы находятся в видеорежиме и требуют явного освобождения.
Ключевая особенность заключается в том, что утечки памяти часто происходят не в JavaScript, а в графическом контексте. Объекты продолжают занимать VRAM даже после потери всех JS-ссылок, если не вызваны методы освобождения ресурсов.
Большинство объектов CesiumJS реализуют контракт уничтожения через
метод destroy() и состояние isDestroyed.
Типичный жизненный цикл:
destroy()Общий паттерн:
if (!resource.isDestroyed()) {
resource.destroy();
}
Многие объекты также поддерживают утилиту:
Cesium.destroyObject(resource);
Она безопасно вызывает destroy() и обнуляет поля.
Viewer агрегирует множество подсистем: сцену, глобус,
imagery layers, primitives, entities, post-processing цепочки.
При вызове:
viewer.destroy();
происходит каскадное освобождение:
Scene)Однако не все внешние ресурсы автоматически очищаются, особенно если они были добавлены вручную вне стандартных коллекций.
Cesium3DTileset является одним из наиболее тяжёлых
объектов по потреблению памяти.
Основные источники нагрузки:
Освобождение выполняется явно:
scene.primitives.remove(tileset);
tileset.destroy();
Критически важно удалять ссылку из сцены до вызова
destroy(), чтобы исключить повторные обращения
рендер-цикла.
Дополнительный контроль кэша:
tileset.maximumScreenSpaceError = 16;
tileset.maximumCacheOverflowBytes = 536870912;
Примитивы (Primitive, GroundPrimitive,
Model) не входят в Entity-систему и требуют ручного
контроля.
Добавление:
const primitive = scene.primitives.add(new Cesium.Primitive({
geometryInstances: instance,
appearance: appearance
}));
Удаление:
scene.primitives.remove(primitive);
primitive.destroy();
Если объект не удалён из коллекции, он продолжает участвовать в рендере и удерживает GPU-ресурсы.
Entity-система автоматически управляет частью ресурсов, но не гарантирует освобождение внешних данных.
Удаление:
viewer.entities.remove(entity);
Полная очистка:
viewer.entities.removeAll();
Проблемные зоны:
entityПри использовании слушателей требуется ручная очистка:
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
ImageryLayer активно использует кэширование тайлов и
текстур.
Удаление слоя:
viewer.imageryLayers.remove(layer, true);
Второй параметр (destroy) критичен: он определяет, будет
ли вызвано освобождение WebGL-ресурсов.
Без явного уничтожения слой может оставлять текстуры в GPU-кэше.
Дополнительные источники памяти:
Глобус (Globe) удерживает:
Очистка:
viewer.scene.globe = undefined;
или более корректно:
viewer.scene.globe.destroy();
Удаление imagery на глобусе:
viewer.scene.imageryLayers.removeAll(true);
Частая причина утечек памяти — сохранённые ссылки в обработчиках событий.
Пример проблемного сценария:
viewer.clock.onTick.addEventListener(update);
Если update замыкает объекты сцены, они не будут
освобождены.
Корректное удаление:
viewer.clock.onTick.removeEventListener(update);
Аналогично:
Scene.postRenderCamera.changedScreenSpaceEventHandlerПри потере WebGL-контекста (например, смена вкладки или GPU reset) Cesium автоматически инвалидирует GPU-ресурсы.
Событие:
viewer.scene.contextLost.addEventListener(() => {});
viewer.scene.contextRestored.addEventListener(() => {});
После восстановления требуется повторная инициализация некоторых ресурсов, особенно кастомных шейдеров и FBO.
Cesium использует внутренние кэши:
Контроль осуществляется через настройки сцены:
viewer.scene.maximumAliasedLineWidth = 1;
viewer.scene.globe.tileCacheSize = 1000;
Также важен контроль запроса данных:
Cesium.RequestScheduler.maximumRequestsPerServer = 6;
Чрезмерные значения приводят к росту RAM и VRAM.
Низкоуровневые объекты (Geometry,
VertexArray) используют TypedArray, которые
могут удерживаться в памяти даже после удаления JS-объекта, если
остаются ссылки в WebGL-буферах.
Типичная ошибка:
Рекомендуемый подход:
Resource управляет сетевыми загрузками и кэшем.
Очистка:
resource.destroy();
Неконтролируемый кэш приводит к накоплению:
Устойчивость памяти в CesiumJS достигается через сочетание факторов:
destroy)