Spec-Zone.ru › JavaScript

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[Symbol.species]
Возвращает конструктор, используемый для создания возвращаемых значений из методов SharedArrayBuffer.

Свойства экземпляра

Эти свойства определены для SharedArrayBuffer.prototype и разделяются всеми экземплярами SharedArrayBuffer.

SharedArrayBuffer.prototype.byteLength
Размер массива в байтах. Он устанавливается при создании массива и может быть изменен только с помощью метода SharedArrayBuffer.prototype.grow(), если SharedArrayBuffer является изменяемым.
SharedArrayBuffer.prototype.constructor
Функция конструктора, создавшая объект экземпляра. Для экземпляров SharedArrayBuffer начальным значением является конструктор SharedArrayBuffer.
SharedArrayBuffer.prototype.growable
Только для чтения. Возвращает true, если SharedArrayBuffer может быть увеличен, или false, если нет.
SharedArrayBuffer.prototype.maxByteLength
Максимальная длина в байтах, до которой может быть увеличен SharedArrayBuffer, только для чтения. Она устанавливается при создании массива и не может быть изменена.
SharedArrayBuffer.prototype[Symbol.toStringTag]
Начальным значением свойства [Symbol.toStringTag] является строка "SharedArrayBuffer". Это свойство используется в Object.prototype.toString().

Методы экземпляра

SharedArrayBuffer.prototype.grow()
Увеличивает SharedArrayBuffer до указанного размера в байтах.
SharedArrayBuffer.prototype.slice()
Возвращает новый 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);

Спецификации

Спецификация
ECMAScript® 2027 Language Specification
# sec-sharedarraybuffer-objects

Совместимость с браузерами

Десктоп Мобильные Сервер
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

См. также

  • Atomics
  • ArrayBuffer
  • Руководство по типизированным массивам 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-Policy
  • Cross-Origin-Embedder-Policy
  • Cross-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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API