Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1005021 of SharedArrayBuffer

  • Revision slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
  • Revision title: SharedArrayBuffer
  • Revision id: 1005021
  • Created:
  • Creator: lth
  • Is current revision? No
  • Comment Correct link to tutorial

Revision Content

{{JSRef}} {{SeeCompatTable}}

The SharedArrayBuffer object is used to represent a generic, fixed-length raw binary data buffer, similar to the {{jsxref("ArrayBuffer")}} object, but in a way that they can be used to create views on shared memory. Unlike an ArrayBuffer, a SharedArrayBuffer cannot become detached.

Syntax

new SharedArrayBuffer(length)

Parameters

length
The size, in bytes, of the array buffer to create.

Return value

A new SharedArrayBuffer object of the specified size. Its contents are initialized to 0.

Description

ArrayBuffers vs. SharedArrayBuffers

JavaScript offers {{jsxref("ArrayBuffer")}} and SharedArrayBuffer objects. They are constructed like this, or using one of the Typed Array types:

var ab = new ArrayBuffer(1024);
var sab = new SharedArrayBuffer(1024);

Web content uses Web Workers to run scripts in background threads. Data gets send from and to the worker by using the {{domxref("Worker.postMessage", "postMessage()")}} method and certain types are so-called transferable objects, that are transferred from one context to another with a zero-copy operation, resulting in high performance.

When transferring an {{jsxref("ArrayBuffer")}} from your main app to a worker script, the original {{jsxref("ArrayBuffer")}} is cleared and no longer usable. Its content is (quite literally) transferred to the worker context.

var uInt8Array = new Uint8Array(1024);
for (var i = 0; i < uInt8Array.length; ++i) {
  uInt8Array[i] = i;
}

var worker = new Worker("worker.js");

// before transferring
console.log(uInt8Array.byteLength); // 1024

worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);

// after transferring
console.log(uInt8Array.byteLength); // 0

Now with a SharedArrayBuffer, you can share this memory with the worker by transferring it using the same postMessage() call.

var sab = new SharedArrayBuffer(1024);

// before transferring
console.log(sab.byteLength); // 1024

worker.postMessage(sab, [sab]);

// after transferring
console.log(sab.byteLength); // 1024

Updating and synchronizing shared memory with Atomic operations

Shared memory can be created and updated simultaneously in workers or the main thread. Depending on the system (the CPU, the OS, the Browser) it can take a while until the change is propagated to all contexts. To synchronize, {{jsxref("Atomics", "atomic", "", 1)}} operations are needed.

APIs accepting SharedArrayBuffer objects

  • {{domxref("WebGLRenderingContext.bufferData()")}}
  • {{domxref("WebGLRenderingContext.bufferSubData()")}}
  • {{domxref("WebGL2RenderingContext.getBufferSubData()")}}

Constructing is required with new operator

SharedArrayBuffer constructors require to be constructed with a {{jsxref("Operators/new", "new")}} operator. Calling a SharedArrayBuffer constructor as a function without new, will throw a {{jsxref("TypeError")}}.

var sab = SharedArrayBuffer(1024);
// TypeError: calling a builtin SharedArrayBuffer constructor 
// without new is forbidden
var sab = new SharedArrayBuffer(1024);

Properties

SharedArrayBuffer.length
The SharedArrayBuffer constructor's length property whose value is 1.
{{jsxref("SharedArrayBuffer.prototype")}}
Allows the addition of properties to all SharedArrayBuffer objects.

Methods

{{jsxref("SharedArrayBuffer.isView", "SharedArrayBuffer.isView(arg)")}}
Returns true if arg is one of the SharedArrayBuffer views, such as typed array objects or a {{jsxref("DataView")}}. Returns false otherwise.

SharedArrayBuffer prototype object

All SharedArrayBuffer instances inherit from {{jsxref("SharedArrayBuffer.prototype")}}.

Properties

{{page('en-US/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype','Properties')}}

Methods

{{page('en-US/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype','Methods')}}

Specifications

Specification Status Comment
{{SpecName('Shared Memory', '#StructuredData.SharedArrayBuffer', 'SharedArrayBuffer')}} {{Spec2('Shared Memory')}} Initial definition.

Browser compatibility

{{CompatibilityTable}}

Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{CompatNo}} [2] {{CompatNo}} {{CompatGeckoDesktop("46")}} [1] {{CompatNo}} {{CompatNo}} {{CompatNo}}
isView() {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}}
slice() {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}}
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{CompatNo}} {{CompatNo}} {{CompatGeckoMobile("46")}} [1] {{CompatNo}} {{CompatNo}} {{CompatNo}}
isView() {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}}
slice() {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}} {{CompatNo}}

[1] This feature is disabled by a preference setting. In about:config, set javascript.options.shared_memory to true

[2] The implementation is under development and needs these runtime flags: --js-flags=--harmony-sharedarraybuffer --enable-blink-feature=SharedArrayBuffer

See also

Revision Source

<div>{{JSRef}} {{SeeCompatTable}}</div>

<p>The <strong><code>SharedArrayBuffer</code></strong> object is used to represent a generic, fixed-length raw binary data buffer, similar to the {{jsxref("ArrayBuffer")}} object, but in a way that they can be used to create views on shared memory. Unlike an <code>ArrayBuffer</code>, a <code>SharedArrayBuffer</code> cannot become detached.</p>

<h2 id="Syntax">Syntax</h2>

<pre class="syntaxbox">
new SharedArrayBuffer(length)
</pre>

<h3 id="Parameters">Parameters</h3>

<dl>
 <dt><code>length</code></dt>
 <dd>The size, in bytes, of the array buffer to create.</dd>
</dl>

<h3 id="Return_value">Return value</h3>

<p>A new <code>SharedArrayBuffer</code> object of the specified size. Its contents are initialized to 0.</p>

<h2 id="Description">Description</h2>

<h3 id="ArrayBuffers_vs._SharedArrayBuffers">ArrayBuffers vs. SharedArrayBuffers</h3>

<p>JavaScript offers {{jsxref("ArrayBuffer")}} and <code>SharedArrayBuffer</code> objects. They are constructed like this, or using one of the <a href="/en-US/docs/Web/JavaScript/Typed_arrays">Typed Array types</a>:</p>

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

<p>Web content uses&nbsp;<a href="/en-US/docs/Web/API/Web_Workers_API">Web Workers</a> to run scripts in background threads. Data gets send from and to the worker by using the {{domxref("Worker.postMessage", "postMessage()")}} method and certain types are so-called <a href="/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects)">transferable objects</a>, that are transferred from one context to another with a zero-copy operation, resulting in high performance.</p>

<p>When transferring an {{jsxref("ArrayBuffer")}} from your main app to a worker script, the original {{jsxref("ArrayBuffer")}} is cleared and no longer usable. Its content is (quite literally) transferred to the worker context.</p>

<pre class="brush: js">
var uInt8Array = new Uint8Array(1024);
for (var i = 0; i &lt; uInt8Array.length; ++i) {
  uInt8Array[i] = i;
}

var worker = new Worker("worker.js");

// before transferring
console.log(uInt8Array.byteLength); // 1024

worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);

// after transferring
console.log(uInt8Array.byteLength); // 0
</pre>

<p>Now with a <code>SharedArrayBuffer</code>, you can share this memory with the worker by transferring it using the same <code>postMessage()</code> call.</p>

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

// before transferring
console.log(sab.byteLength); // 1024

worker.postMessage(sab, [sab]);

// after transferring
console.log(sab.byteLength); // 1024</pre>

<h3 id="Updating_and_synchronizing_shared_memory_with_Atomic_operations">Updating and synchronizing shared memory with Atomic operations</h3>

<p>Shared memory can be created and updated simultaneously in workers or the main thread. Depending on the system (the CPU, the OS, the Browser) it can take a while until the change is propagated to all contexts. To synchronize, {{jsxref("Atomics", "atomic", "", 1)}} operations are needed.</p>

<h3 id="APIs_accepting_SharedArrayBuffer_objects">APIs accepting <code>SharedArrayBuffer</code> objects</h3>

<ul>
 <li>{{domxref("WebGLRenderingContext.bufferData()")}}</li>
 <li>{{domxref("WebGLRenderingContext.bufferSubData()")}}</li>
 <li>{{domxref("WebGL2RenderingContext.getBufferSubData()")}}</li>
</ul>

<h3 id="Constructing_is_required_with_new_operator">Constructing is required with <code>new</code> operator</h3>

<p><code>SharedArrayBuffer</code> constructors require to be constructed with a {{jsxref("Operators/new", "new")}} operator. Calling a <code>SharedArrayBuffer</code> constructor as a function without <code>new</code>, will throw a {{jsxref("TypeError")}}.</p>

<pre class="brush: js example-bad">
var sab = SharedArrayBuffer(1024);
// TypeError: calling a builtin SharedArrayBuffer constructor 
// without new is forbidden</pre>

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

<h2 id="Properties">Properties</h2>

<dl>
 <dt><code>SharedArrayBuffer.length</code></dt>
 <dd>The <code>SharedArrayBuffer</code> constructor's length property whose value is 1.</dd>
 <dt>{{jsxref("SharedArrayBuffer.prototype")}}</dt>
 <dd>Allows the addition of properties to all <code>SharedArrayBuffer</code> objects.</dd>
</dl>

<h2 id="Methods">Methods</h2>

<dl>
 <dt>{{jsxref("SharedArrayBuffer.isView", "SharedArrayBuffer.isView(arg)")}}</dt>
 <dd>Returns <code>true</code> if <code>arg</code> is one of the SharedArrayBuffer views, such as <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray">typed array objects</a> or a {{jsxref("DataView")}}. Returns <code>false</code> otherwise.</dd>
</dl>

<h2 id="SharedArrayBuffer_prototype_object"><code>SharedArrayBuffer</code> prototype object</h2>

<p>All <code>SharedArrayBuffer</code> instances inherit from {{jsxref("SharedArrayBuffer.prototype")}}.</p>

<h3 id="Properties_2">Properties</h3>

<p>{{page('en-US/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype','Properties')}}</p>

<h3 id="Methods_2">Methods</h3>

<p>{{page('en-US/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype','Methods')}}</p>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('Shared Memory', '#StructuredData.SharedArrayBuffer', 'SharedArrayBuffer')}}</td>
   <td>{{Spec2('Shared Memory')}}</td>
   <td>Initial definition.</td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<p>{{CompatibilityTable}}</p>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Edge</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatNo}} [2]</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatGeckoDesktop("46")}} [1]</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
  <tr>
   <td><code>isView()</code></td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
  <tr>
   <td><code>slice()</code></td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatGeckoMobile("46")}} [1]</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
  <tr>
   <td><code>isView()</code></td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
  <tr>
   <td><code>slice()</code></td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
 </tbody>
</table>
</div>

<p>[1] This feature is disabled by a preference setting. In about:config, set <code>javascript.options.shared_memory</code> to <code>true</code>.&nbsp;</p>

<p>[2] The implementation is under development and needs these runtime flags: <code>--js-flags=--harmony-sharedarraybuffer --enable-blink-feature=SharedArrayBuffer</code></p>

<h2 id="See_also">See also</h2>

<ul>
 <li>{{jsxref("Atomics")}}</li>
 <li>{{jsxref("ArrayBuffer")}}</li>
 <li><a href="/en-US/docs/Web/JavaScript/Typed_arrays">JavaScript typed arrays</a></li>
 <li><a href="/en-US/docs/Web/API/Web_Workers_API">Web Workers</a></li>
 <li><a href="https://github.com/lars-t-hansen/parlib-simple">parlib-simple </a>– a simple library providing synchronization and work distribution abstractions.</li>
 <li><a href="https://github.com/tc39/ecmascript_sharedmem/blob/master/TUTORIAL.md">Shared Memory – a brief tutorial</a></li>
</ul>
Revert to this revision