---
title: SharedArrayBuffer
slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
tags:
  - Класс
  - JavaScript
  - Разделяемая память
  - SharedArrayBuffer
  - TypedArrays
---
<div>{{JSRef}}</div>

<p>Объект <strong><code>SharedArrayBuffer</code></strong> подобен ArrayBuffer, то есть это буфер фиксированной длины, использующийся для хранения любых бинарных данных. Главное отличие <code>SharedArrayBuffer</code> от <code>ArrayBuffer</code> заключается в том, что он используется для создания разделяемой области памяти. В отличие от <code>ArrayBuffer</code> <code>SharedArrayBuffer</code> не может быть откреплён от соответствующей ему области памяти.</p>

<h2 id="Описание">Описание</h2>

<h3 id="Выделение_и_совместное_использование_памяти">Выделение и совместное использование памяти</h3>

<p>Для совместного использования памяти с помощью объекта {{jsxref("SharedArrayBuffer")}} между одним агентом в кластере и другим (агентом может быть как основная программа страницы сайта, так и один из её веб-воркеров) используются <code><a href="/ru/docs/Web/API/Worker/postMessage">postMessage</a></code> и <a href="/ru/docs/Web/API/Web_Workers_API/Structured_clone_algorithm">алгоритм структурированного клонирования</a>.</p>

<p>Алгоритм структурированного клонирования принимает <code>SharedArrayBuffers</code> и <code>TypedArrays</code>, отображённый в <code>SharedArrayBuffers</code>. В обоих случаях объект <code>SharedArrayBuffer</code> передаётся получателю, что приводит к появлению нового приватного объекта SharedArrayBuffer внутри агента-получателя (так же как для {{jsxref("ArrayBuffer")}}). Оба объекта <code>SharedArrayBuffer</code> ссылаются на один и тот же блок общих данных, и побочный эффект, изменяющий блок данных в одном из агентов, в итоге проявится в другом агенте.</p>

<pre class="brush: js">var sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);
</pre>

<h3 id="Обновление_и_синхронизация_разделяемой_памяти_с_помощью_атомарных_операций">Обновление и синхронизация разделяемой памяти с помощью атомарных операций</h3>

<p>Разделяемую память можно создавать и изменять одновременно в воркерах или основном потоке. В зависимости от системы (ЦПУ, ОС, браузера), распространение изменений по всем контекстам может занять некоторое время. Для синхронизации необходимы {{jsxref("Атомарные", "атомарные", "", 1)}} операции .</p>

<h3 id="API_принимающие_объекты_SharedArrayBuffer">API, принимающие объекты <code>SharedArrayBuffer</code></h3>

<ul>
 <li><a href="/en-US/docs/Web/API/WebGLRenderingContext/bufferData" title="Метод WebGLRenderingContext.bufferData() WebGL API инициализирует и создает хранилище данных буферного объекта."><code>WebGLRenderingContext.bufferData()</code></a></li>
 <li><a href="/en-US/docs/Web/API/WebGLRenderingContext/bufferSubData" title="Метод WebGLRenderingContext.bufferSubData() WebGL API обновляет подмножество хранилища данных буферного объекта."><code>WebGLRenderingContext.bufferSubData()</code></a></li>
 <li><a href="/en-US/docs/Web/API/WebGL2RenderingContext/getBufferSubData" title="Метод WebGL2RenderingContext.getBufferSubData() WebGL 2 API считывает данные из привязанной точки буфера и записывает их в ArrayBuffer или SharedArrayBuffer."><code>WebGL2RenderingContext.getBufferSubData()</code></a></li>
</ul>

<h3 id="Требования_безопасности">Требования безопасности</h3>

<p>Разделяемая память и таймеры высокого разрешения были <a href="https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/">отключены в начале 2018 года</a> из-за атаки <a href="https://ru.wikipedia.org/wiki/Spectre_(%D1%83%D1%8F%D0%B7%D0%B2%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C)">Spectre</a>. В 2020 году был стандартизирован новый, безопасный подход, чтобы включить разделяемую память обратно. При следовании следующим мерам безопасности <code><a href="/ru/docs/Web/API/Window/postMessage">postMessage()</a> не будет выкидывать исключение для <code>SharedArrayBuffer</code>, и разделяемая память будет доступна в разных потоках.</p>

<p>Основное требование — ваш документ должен находиться в <a href="/en-US/docs/Web/Security/Secure_Contexts">безопасном контексте</a></p>

<p>Для документов верхнего уровня нужно устновить два заголовка, чтобы изолировать ваш сайт от других источников (cross-origin):</p>

<ul>
 <li><a href="/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy"><code>Cross-Origin-Opener-Policy</code></a> со значением <code>same-origin</code> (защищает ваш источник от атаки)</li>
 <li><a href="/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy"><code>Cross-Origin-Embedder-Policy</code></a> со значением <code>require-corp</code> (защищает жертв от вашего источника)</li>
</ul>

<pre class="brush: plain">Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
</pre>

<p>Чтобы проверить, что изоляция от других источников прошла успешно, протестируйте свойство <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/crossOriginIsolated">crossOriginIsolated</a></code>, доступное для контекстов окна и воркера:</p>

<pre class="brush: js">if (crossOriginIsolated) {
  // Начни работу с SharedArrayBuffer
} else {
  // Сделай что-то другое
}</pre>

<p>Ознакомьтесь с <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/Planned_changes">планируемыми изменениями разделяемой памяти</a>, которые начинают внедряться в браузерах (например, в Firefox 79).</p>

<h3 id="Всегда_используйте_оператор_new_для_создания_SharedArrayBuffer">Всегда используйте оператор new для создания SharedArrayBuffer</h3>

<p>Конструкторы <code>SharedArrayBuffer</code> необходимо вызывать с помощью оператора {{jsxref("Operators/new", "new")}}. Вызов конструктора <code>SharedArrayBuffer</code> как функции без указания <code>new</code> вызовет ошибку {{jsxref("TypeError")}}.</p>

<pre class="brush: js example-bad">var sab = SharedArrayBuffer(1024);
// TypeError: вызов встроенного конструктора SharedArrayBuffer
// без new запрещено</pre>

<pre class="brush: js example-good">var sab = new SharedArrayBuffer(1024);</pre>

<h2 id="Конструктор">Конструктор</h2>

<dl>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/SharedArrayBuffer"><code>SharedArrayBuffer()</code></a></dt>
 <dd>Создаёт новый объект <code>SharedArrayBuffer</code>.</dd>
</dl>

<h3 id="Свойства">Свойства</h3>

<dl>
 <dt>{{jsxref("SharedArrayBuffer.prototype.byteLength")}}</dt>
 <dd>Размер буферного массива в байтах. Задаётся при создании массива и не может быть изменён. <strong>Только для чтения.</strong></dd>
</dl>

<h2 id="Методы">Методы</h2>

<dl>
 <dt>{{jsxref("SharedArrayBuffer.slice", "SharedArrayBuffer.prototype.slice(begin, end)")}}</dt>
 <dd>Возвращает новый <code>SharedArrayBuffer</code>, чьё содержимое — копия байтов изначального <code>SharedArrayBuffer</code> с <code>begin</code> (начала) включительно до <code>end</code> (конца), но не включая его. Если параметры <code>begin</code> или <code>end</code> отрицательны, метод обращается к индексу массива, начиная с конца, а не с начала.</dd>
</dl>

<h2 id="Примеры">Примеры</h2>

<h3 id="Создание_нового_SharedArrayBuffer">Создание нового SharedArrayBuffer</h3>

<pre class="brush: js">var sab = new SharedArrayBuffer(1024);</pre>

<h3 id="Нарезание_SharedArrayBuffer">Нарезание SharedArrayBuffer</h3>

<pre class="brush: js">sab.slice();    // SharedArrayBuffer { byteLength: 1024 }
sab.slice(2);   // SharedArrayBuffer { byteLength: 1022 }
sab.slice(-2);  // SharedArrayBuffer { byteLength: 2 }
sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }</pre>

<h3 id="Использование_в_буфере_WebGL">Использование в буфере WebGL</h3>

<pre class="brush: js">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);</pre>

<h2 id="Спецификации">Спецификации</h2>

{{Specifications}}

<h2 id="Поддержка_браузерами">Поддержка браузерами</h2>

<p>{{Compat("javascript.builtins.SharedArrayBuffer")}}</p>

<h2 id="Смотрите_также">Смотрите также</h2>

<ul>
 <li>{{jsxref("Atomics")}}</li>
 <li>{{jsxref("ArrayBuffer")}}</li>
 <li><a href="/ru/docs/Web/JavaScript/Typed_arrays">Типизированные массивы JavaScript</a></li>
 <li><a href="/ru/docs/Web/API/Web_Workers_API">Веб-воркеры</a></li>
 <li><a href="https://github.com/lars-t-hansen/parlib-simple">parlib-simple</a> — простая библиотека, предоставляющая синхронизацию и абстракции для распределённых работ.</li>
 <li><a href="https://github.com/tc39/ecmascript_sharedmem/blob/master/TUTORIAL.md">Разделяемая память — краткая инструкция</a></li>
 <li>
  <p><a href="https://hacks.mozilla.org/2016/05/a-taste-of-javascripts-new-parallel-primitives/">Немного о новых примитивах JavaScript для параллелизации работ – Mozilla Hacks</a></p>
 </li>
</ul>