--- title: SharedArrayBuffer slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer tags: - Class - JavaScript - Shared Memory - SharedArrayBuffer - TypedArrays browser-compat: javascript.builtins.SharedArrayBuffer translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer ---
SharedArrayBuffer オブジェクトは、固定長の生バイナリデータバッファーのジェネリックを表すために使用されます。{{jsxref("ArrayBuffer")}} オブジェクトと似ていますが、こちらは共有メモリー上にビューを生成するために使用されます。 ArrayBuffer と異なり、SharedArrayBuffer は分離できません。
クラスター内のあるエージェントから別のエージェント (エージェントとは、ウェブページのメインプログラムまたはそのウェブワーカーのひとつ) へ、{{jsxref("SharedArrayBuffer")}} オブジェクトを使用してメモリーを共有するために、postMessage と構造化クローンを使用します。
構造化クローンアルゴリズムは SharedArrayBuffers と、SharedArrayBuffers にマッピングされた TypedArrays を受け入れます。どちらの場合も SharedArrayBuffer オブジェクトは受信者に転送されて、受信側のエージェントで新たなプライベートの SharedArrayBuffer オブジェクトになります ({{jsxref("ArrayBuffer")}} と同じように)。しかし、2 つの SharedArrayBuffer オブジェクトから参照される共有データブロックは同一のデータブロックであり、あるエージェントによるブロックへの副作用は、結果的に他方のエージェントからも見えます。
var sab = new SharedArrayBuffer(1024); worker.postMessage(sab);
共有メモリーは、ワーカー内でもメインスレッド内でも同時に生成や更新ができます。システム (CPU、 OS、ブラウザー) によっては、変更がすべてのコンテキストに通知されるまでに少々時間がかかります。同期するためには、{{jsxref("Atomics", "atomic", "", 1)}} 操作が必要です。
WebGLRenderingContext.bufferData()WebGLRenderingContext.bufferSubData()WebGL2RenderingContext.getBufferSubData()共有メモリーと高解像度タイマーは、 Spectre の対策として 2018 年の初めに事実上無効化されました。 2020 年には、共有メモリを再び有効にするために、新しい安全なアプローチが標準化されました。いくつかのセキュリティ対策を施すことで、 postMessage() が SharedArrayBuffer オブジェクトに対して例外を発生しなくなり、スレッド間の共有メモリが利用できるようになります。
基本的な要件として、文書が安全なコンテキストにある必要があります。
最上位の文書では、サイトにオリジン間の分離性を持たせるため、次の2つのヘッダーを設定する必要があります。
Cross-Origin-Opener-Policy で same-origin の値を指定すること (オリジンを攻撃者から守るため)Cross-Origin-Embedder-Policy で require-corp の値を指定すること (被害者を自分のオリジンから守るため)Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
オリジン間の分離が成功したかどうかは、ウィンドウとワーカーのコンテキストで利用できる crossOriginIsolated プロパティを使って確認することができます。
if (crossOriginIsolated) {
// Post SharedArrayBuffer
} else {
// Do something else
}
また、ブラウザー (Firefox 79など) で展開され始めている共有メモリーの計画的な変更も参照してください。
SharedArrayBuffer コンストラクターは、{{jsxref("Operators/new", "new")}} 演算子で呼び出す必要があります。new 演算子なしで関数として SharedArrayBuffer コンストラクターを呼び出すと、{{jsxref("TypeError")}} が発生します。
var sab = SharedArrayBuffer(1024); // TypeError: calling a builtin SharedArrayBuffer constructor // without new is forbidden
var sab = new SharedArrayBuffer(1024);
SharedArrayBuffer()SharedArrayBuffer オブジェクトを生成します。SharedArrayBuffer を作成し、その中身をこの SharedArrayBuffer の begin の位置から end の位置の一つ手前までのバイトをコピーして返します。 begin または end が負の数の場合は、配列の先頭からではなく末尾からの位置で参照します。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);
{{Compat}}