SharedArrayBuffer
Базовый уровень Широко доступно
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с декабря 2021 года.
Объект SharedArrayBuffer используется для представления общего буфера двоичных данных, аналогичного объекту ArrayBuffer, но таким образом, чтобы его можно было использовать для создания представлений в общей памяти. SharedArrayBuffer не является передаваемым объектом, в отличие от ArrayBuffer, который является передаваемым.
Описание
Для обмена памятью с использованием объектов SharedArrayBuffer из одного агента в кластере другому (агент — это либо основная программа веб-страницы, либо один из ее веб-воркеров), используется postMessage и структурированное клонирование.
Алгоритм структурированного клонирования принимает объекты SharedArrayBuffer и типизированные массивы, отображенные на объекты SharedArrayBuffer. В обоих случаях объект SharedArrayBuffer передается получателю, в результате чего создается новый, частный объект SharedArrayBuffer в принимающем агенте (как и для ArrayBuffer). Однако общий блок данных, на который ссылаются два объекта SharedArrayBuffer, является одним и тем же блоком данных, и побочный эффект для блока в одном агенте в конечном итоге станет видимым в другом агенте.
const sab = new SharedArrayBuffer(1024); worker.postMessage(sab);
Общая память может создаваться и обновляться одновременно в рабочих процессах или в основном потоке. В зависимости от системы (ЦПУ, ОС, браузер) изменение может занять некоторое время, пока оно не будет распространено на все контексты. Для синхронизации требуются атомарные операции.
Объекты SharedArrayBuffer используются некоторыми веб-API, такими как:
WebGLRenderingContext.bufferData()WebGLRenderingContext.bufferSubData()WebGL2RenderingContext.getBufferSubData()
Требования безопасности
Общая память и таймеры высокого разрешения были фактически отключены в начале 2018 года в свете Spectre. В 2020 году был стандартизирован новый, безопасный подход для повторного включения общей памяти.
Для использования общей памяти ваш документ должен находиться в безопасном контексте и быть изолированным по отношению к источникам. Вы можете использовать свойства Window.crossOriginIsolated и WorkerGlobalScope.crossOriginIsolated для проверки, изолирован ли документ по отношению к источникам:
const myWorker = new Worker("worker.js");
if (crossOriginIsolated) {
const buffer = new SharedArrayBuffer(16);
myWorker.postMessage(buffer);
} else {
const buffer = new ArrayBuffer(16);
myWorker.postMessage(buffer);
}
Когда документ изолирован по отношению к источникам, postMessage() больше не вызывает исключений для объектов SharedArrayBuffer, и, следовательно, общая память между потоками доступна.
Доступность API
В зависимости от того, приняты ли вышеуказанные меры безопасности, различные API для обмена памятью имеют разную доступность:
- Объект
Atomicsвсегда доступен. -
Объекты
SharedArrayBufferв принципе всегда доступны, но, к сожалению, конструктор в глобальном объекте скрыт, если не установлены два упомянутых выше заголовка, для совместимости с веб-контентом. Есть надежда, что это ограничение может быть снято в будущем.WebAssembly.Memoryпо-прежнему может использоваться для получения экземпляра. - Если два упомянутых выше заголовка не установлены, различные API
postMessage()вызовут исключения для объектовSharedArrayBuffer. Если они установлены,postMessage()на объектахWindowи выделенных воркерах будут функционировать и позволят обмениваться памятью.
Общая память WebAssembly
Объекты WebAssembly.Memory могут быть созданы с флагом конструктора shared. Когда этот флаг установлен в true, сконструированный объект Memory может быть совместно использован между воркерами через postMessage(), как и SharedArrayBuffer, а базовый buffer объекта Memory является SharedArrayBuffer. Следовательно, требования, перечисленные выше для совместного использования SharedArrayBuffer между воркерами, также применяются к совместному использованию WebAssembly.Memory.
Предложение WebAssembly Threads также определяет новый набор атомарных инструкций. Точно так же, как SharedArrayBuffer и его методы безусловно включены (и только совместное использование между потоками управляется новыми заголовками), атомарные инструкции WebAssembly также безусловно разрешены.
Увеличение размера SharedArrayBuffers
Объекты SharedArrayBuffer можно сделать увеличиваемыми, включив опцию maxByteLength при вызове конструктора SharedArrayBuffer(). Вы можете проверить, является ли SharedArrayBuffer увеличиваемым и каков его максимальный размер, получив доступ к его свойствам growable и maxByteLength соответственно. Вы можете присвоить новый размер увеличиваемому SharedArrayBuffer с помощью вызова grow(). Новые байты инициализируются нулями.
Эти функции делают увеличение SharedArrayBuffer более эффективным — в противном случае вам придется копировать буфер с новым размером. Это также дает JavaScript паритет с WebAssembly в этом отношении (линейная память Wasm может быть изменена с помощью WebAssembly.Memory.prototype.grow()).
По соображениям безопасности SharedArrayBuffer нельзя уменьшать в размере, только увеличивать.
Конструктор
- Создает новый объект
SharedArrayBuffer.
Статические свойства
- Возвращает конструктор, используемый для создания возвращаемых значений из методов
SharedArrayBuffer.
Свойства экземпляра
Эти свойства определены для SharedArrayBuffer.prototype и разделяются всеми экземплярами SharedArrayBuffer.
- Размер массива в байтах. Он устанавливается при создании массива и может быть изменен только с помощью метода
SharedArrayBuffer.prototype.grow(), еслиSharedArrayBufferявляется изменяемым. - Функция конструктора, создавшая объект экземпляра. Для экземпляров
SharedArrayBufferначальным значением является конструкторSharedArrayBuffer. - Только для чтения. Возвращает
true, еслиSharedArrayBufferможет быть увеличен, илиfalse, если нет. - Максимальная длина в байтах, до которой может быть увеличен
SharedArrayBuffer, только для чтения. Она устанавливается при создании массива и не может быть изменена. - Начальным значением свойства
[Symbol.toStringTag]является строка"SharedArrayBuffer". Это свойство используется вObject.prototype.toString().
Методы экземпляра
- Увеличивает
SharedArrayBufferдо указанного размера в байтах. - Возвращает новый
SharedArrayBuffer, содержимое которого является копией байтовSharedArrayBufferизbegin(включительно) доend(исключительно). Еслиbeginилиendотрицательны, они относятся к индексу с конца массива, а не с начала.
Примеры
Обратите внимание, что эти примеры нельзя запускать напрямую из консоли или произвольной веб-страницы, потому что SharedArrayBuffer не определен, если его требования безопасности не выполнены.
Создание нового SharedArrayBuffer
const sab = new SharedArrayBuffer(1024);
Создание среза SharedArrayBuffer
sab.slice(); // SharedArrayBuffer { byteLength: 1024 }
sab.slice(2); // SharedArrayBuffer { byteLength: 1022 }
sab.slice(-2); // SharedArrayBuffer { byteLength: 2 }
sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }
Использование в буфере WebGL
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, sab, gl.STATIC_DRAW);
Спецификации
Совместимость с браузерами
| Десктоп | Мобильные | Сервер | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on iOS | Samsung Internet | WebView Android | WebView on iOS | Bun | Deno | Node.js | |
SharedArrayBuffer |
68 |
79 |
79 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
Нет |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
@@species |
68 |
79 |
79 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
Нет |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
SharedArrayBuffer |
68 |
79 |
79 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
Нет |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
byteLength |
68 |
79 |
79 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
Нет |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
grow |
111 |
111 |
128 |
97 |
16.4 |
111 |
128 |
75 |
16.4 |
22.0 |
Нет |
16.4 |
1.0.0 |
1.33 |
20.0.0 |
growable |
111 |
111 |
128 |
97 |
16.4 |
111 |
128 |
75 |
16.4 |
22.0 |
Нет |
16.4 |
1.0.0 |
1.33 |
20.0.0 |
maxByteLength |
111 |
111 |
128 |
97 |
16.4 |
111 |
128 |
75 |
16.4 |
22.0 |
Нет |
16.4 |
1.0.0 |
1.33 |
20.0.0 |
slice |
68 |
79 |
79 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
Нет |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
См. также
AtomicsArrayBuffer- Руководство по типизированным массивам JavaScript
- Web Workers
- Shared Memory – краткое руководство в предложении TC39 ecmascript-sharedmem
- A Taste of JavaScript's New Parallel Primitives на hacks.mozilla.org (2016)
- COOP и COEP: объяснение от команды Chrome (2020)
Cross-Origin-Opener-PolicyCross-Origin-Embedder-PolicyCross-Origin-Resource-Policy-
Window.crossOriginIsolatedиWorkerGlobalScope.crossOriginIsolated - Обновления SharedArrayBuffer в Android Chrome 88 и Desktop Chrome 92 на developer.chrome.com (2021)
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer