SharedArrayBuffer
object is used to represent a generic, fixed-length raw binary data buffer, similar to the
ArrayBuffer
object, but in a way that they can be used to create views on shared memory. Unlike an
ArrayBuffer
,
SharedArrayBuffer
cannot become detached.
To share memory using
SharedArrayBuffer
objects from one agent in the cluster to another (an agent is either the web page’s main program or one of its web workers),
postMessage
and
structured cloning
被使用。
The structured clone algorithm accepts
SharedArrayBuffers
and
TypedArrays
mapped onto
SharedArrayBuffers
. In both cases, the
SharedArrayBuffer
object is transmitted to the receiver resulting in a new, private SharedArrayBuffer object in the receiving agent (just as for
ArrayBuffer
). However, the shared data block referenced by the two
SharedArrayBuffer
objects is the same data block, and a side effect to the block in one agent will eventually become visible in the other agent.
var sab = new SharedArrayBuffer(1024); worker.postMessage(sab);
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, atomic operations are needed.
WebGLRenderingContext.bufferData()
WebGLRenderingContext.bufferSubData()
WebGL2RenderingContext.getBufferSubData()
Shared memory and high-resolution timers were effectively
disabled at the start of 2018
in light of
Spectre
. In 2020, a new, secure approach has been standardized to re-enable shared memory. With a few security measures,
postMessage()
will no longer throw for
SharedArrayBuffer
objects and shared memory across threads will be available:
As a baseline requirement, your document needs to be in a secure context .
For top-level documents, two headers will need to be set to cross-origin isolate your site:
Cross-Origin-Opener-Policy
with
same-origin
as value (protects your origin from attackers)
Cross-Origin-Embedder-Policy
with
require-corp
as value (protects victims from your origin)
Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
To check if cross origin isolation has been successful, you can test against the
crossOriginIsolated
property available to window and worker contexts:
if (crossOriginIsolated) {
// Post SharedArrayBuffer
} else {
// Do something else
}
另请参阅 Planned changes to shared memory which is starting to roll out to browsers (Firefox 79, for example.)
SharedArrayBuffer
constructors are required to be constructed with a
new
operator. Calling a
SharedArrayBuffer
constructor as a function without
new
will throw a
TypeError
.
var sab = SharedArrayBuffer(1024); // TypeError: calling a builtin SharedArrayBuffer constructor // without new is forbidden
var sab = new SharedArrayBuffer(1024);
SharedArrayBuffer()
SharedArrayBuffer
对象。
SharedArrayBuffer.prototype.byteLength
SharedArrayBuffer.prototype.slice(begin, end)
SharedArrayBuffer
whose contents are a copy of this
SharedArrayBuffer
's bytes from
begin
, inclusive, up to
end
, exclusive. If either
begin
or
end
is negative, it refers to an index from the end of the array, as opposed to from the beginning.
var sab = new SharedArrayBuffer(1024);
sab.slice(); // SharedArrayBuffer { byteLength: 1024 }
sab.slice(2); // SharedArrayBuffer { byteLength: 1022 }
sab.slice(-2); // SharedArrayBuffer { byteLength: 2 }
sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }
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 (ECMA-262)
The definition of 'SharedArrayBuffer' in that specification. |
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
SharedArrayBuffer
|
Chrome
68
|
Edge
79
|
Firefox
79
|
IE No | Opera No | Safari 10.1 — 11 |
WebView Android
60 — 63
|
Chrome Android
60 — 63
|
Firefox Android
57
Disabled
|
Opera Android No | Safari iOS 10.3 — 11 |
Samsung Internet Android
No
|
nodejs 8.10.0 |
SharedArrayBuffer()
构造函数
|
Chrome
68
|
Edge
79
|
Firefox
79
|
IE No | Opera No | Safari 10.1 — 11 |
WebView Android
60 — 63
|
Chrome Android
60 — 63
|
Firefox Android
57
Disabled
|
Opera Android No | Safari iOS 10.3 — 11 |
Samsung Internet Android
No
|
nodejs 8.10.0 |
byteLength
|
Chrome
68
|
Edge
79
|
Firefox
79
|
IE No | Opera No | Safari 10.1 — 11 |
WebView Android
60 — 63
|
Chrome Android
60 — 63
|
Firefox Android
57
Disabled
|
Opera Android No | Safari iOS 10.3 — 11 |
Samsung Internet Android
No
|
nodejs 8.10.0 |
slice
|
Chrome
68
|
Edge
79
|
Firefox
79
|
IE No | Opera No | Safari 10.1 — 11 |
WebView Android
60 — 63
|
Chrome Android
60 — 63
|
Firefox Android
57
Disabled
|
Opera Android No | Safari iOS 10.3 — 11 |
Samsung Internet Android
No
|
nodejs 8.10.0 |
完整支持
不支持
见实现注意事项。
用户必须明确启用此特征。
Atomics
ArrayBuffer
A Taste of JavaScript’s New Parallel Primitives – Mozilla Hacks
SharedArrayBuffer
Function
Object
Object.prototype.__defineGetter__()
Object.prototype.__defineSetter__()
Object.prototype.__lookupGetter__()
Object.prototype.__lookupSetter__()
Object.prototype.hasOwnProperty()
Object.prototype.isPrototypeOf()
Object.prototype.propertyIsEnumerable()
Object.prototype.toLocaleString()
Object.prototype.toSource()
Object.prototype.toString()
Object.prototype.valueOf()
Object.setPrototypeOf()