ermouth: (Default)
[personal profile] ermouth

Мы все привыкли, что в javascript-коде, особенно клиентском, можно особо насчёт RAM не париться. Автоматические сборщики мусора уже очень хороши во всех браузерах и прекрасно переваривают даже существенно корявый код и сложно зацикленные указатели.

Но есть одно исключение, когда памятью в js нужно управлять прямо – то-есть делать allocate-deallocate кодом, а не полагаться на автомат. В полный рост это исключение проявляется в noBackend приложениях.

Жизнь без пермалинков

Дело в том, что для бинари-ресурсов, хранимых локально в браузере, не существует пермалинков. То-есть, если надо вставить картинку, то src="http://url.com/image.jpg" написать не получится – нет у картинок урла.

И у документов для скачивания нет. И у скриптов. Проблема разрешима двумя путями:

1. Вставлять в атрибут src полный base64 картинки. Так, например, сделано в http://cloudwall.me/os/docs/app.html – картинки заинлайнены. Это хорошо для единичных картинок и называется data URL (RFC 2397). Что-то длинное (десятки мегабайт) так заинлайнить не получится – можно обвалить DOM.

2. Можно загружать картинки из БД как иммутабельный Blob и делать из блобов objectURL – специальный сессионный URL, который живёт до перезагрузки страницы, и который как-бы шорткат на реальные данные в блобе. Это хорошо для повторяющихся картинок – иконки там, то-сё. Ещё так можно давать ссылки для скачивания на большие куски данных – десятки мегабайт вполне ок.

Выглядят такие ссылки примерно так blob:http%3A//jquerymy.com/96e56d1d-e76d-41a8-8c7a-a77035eb95d4, живьём посмотреть можно тут http://jquerymy.com/api.html#CW-inlined-re.

Если перезагрузить страницу с примером, ссылка поменяется.

Чем же страшен objectURL?

С блобами и objectURL всё не так просто. Разумно было бы предположить, что раз Blob штука иммутабельная – то и objectURL из этого блоба должен получаться одинаковый, если мы его в рамках одной сессии попросим несколько раз сгенерить из одних и тех же данных.

А вот фиг.

УРЛ каждый раз будет разный, даже в пределах одной сессии. Более того, браузер продублирует исходные данные столько раз, сколько мы попросили сделать урл из блоба. Блоб то может под garbage collect-ом невзначай умереть – а ссылка должна жить, и данные под ней тоже.

В js-мире objectURL – единственная сущность, которая имеет deallocate. Во избежание утечек памяти мы должны явно освободить УРЛ, как только он стал не нужен.

Как детектить мусор?

Главный вопрос – определить момент, когда ресурс, занимающий память, и сессионый УРЛ для него, действительно стали больше не нужны.

Доверять приложениям самим освобождать ресурсы ненадёжно – приложение может по дороге помереть, а ресурс останется занятым.

Стало быть, это должна делать ОС.

Раз основной (практически – почти единственный) источник появления таких УРЛов – файловые аттачи в локальной БД, значит надо централизовать их чтение и генерацию сессионных УРЛов.

То-есть, мы освобождаем память, как только закрылся последний экземпляр приложения, читавшего этот аттач к документу. Выделяем память, соответственно, когда аттач читается впервые.

В CloudWall спецом для этого сделан метод для чтения аттачей, который доступен внутри любого приложения.

Отвлечённое соображение

Вообще, полное отсутствие в модных фреймворках типа React+Flux даже намёков на понимание существования проблемы делает их, по-хорошему, неюзабельными для offline/noBackend мира.

То-есть, как только мы пробуем сделать что-то с помощью React, что будет self-contained приложением для noBackend мира, мы практически сразу наталкиваемся на невероятный геморрой и отсутствие тулсетов.

Вариантов всего два. Либо мы должны брать PhoneGap и делать из сайта полноценное приложение под Андроид (иОС, МакОС) – чтобы засунуть туда все ресурсы. Либо расчитывать, что мы во время работы будем онлайн.

$.my + cloudwall, напротив, позволяют вообще по этому поводу не париться. В cloudwall codebase управление памятью кста – всего 150 строк.

---

ЗЫ. Есть ещё один случай, когда надо “руками” allocate/deallocate делать – как ни странно, это нужно для управления CSS-стилями, локальными для приложений, – но про это в другой раз.

Profile

ermouth: (Default)
ermouth

November 2021

S M T W T F S
 123456
78910111213
14151617181920
21 222324252627
282930    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 28th, 2025 09:19 am
Powered by Dreamwidth Studios