--- 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}}