26 メモリの管理

26.1 WeakRef オブジェクト

WeakRef は、ターゲットとなるオブジェクトまたはシンボルをガベージコレクションから保護せずに参照するためのオブジェクトである。ターゲットがまだガベージコレクションに回収されていない場合、WeakRef は逆参照してターゲット値へアクセスできる。

26.1.1 WeakRef コンストラクタ

WeakRef コンストラクタは次の通り:

  • %WeakRef% である。
  • グローバルオブジェクト"WeakRef" プロパティの初期値である。
  • コンストラクタとして呼び出されたとき新しい WeakRef を生成し初期化する。
  • 関数として呼び出されることを意図しておらず、そのように呼び出された場合は例外を投げる。
  • クラス定義の extends 句における値として使用できる。指定された WeakRef の挙動を継承することを意図するサブクラスのコンストラクタは、WeakRef.prototype 組み込みメソッドをサポートするために必要な内部状態でサブクラスインスタンスを生成・初期化するため、WeakRef コンストラクタへの super 呼び出しを含めなければならない。

26.1.1.1 WeakRef ( target )

この関数は呼び出されると次の手順を実行する:

  1. もし NewTarget が undefined なら TypeError 例外を投げる。
  2. もし CanBeHeldWeakly(target) が false なら TypeError 例外を投げる。
  3. weakRef を ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRef.prototype%", « [[WeakRefTarget]] ») とする。
  4. AddToKeptObjects(target) を実行する。
  5. weakRef.[[WeakRefTarget]]target を設定する。
  6. weakRef を返す。

26.1.2 WeakRef コンストラクタのプロパティ

WeakRef コンストラクタは次の通り:

  • その [[Prototype]] 内部スロットの値は %Function.prototype% である。
  • 以下のプロパティを持つ:

26.1.2.1 WeakRef.prototype

WeakRef.prototype の初期値は WeakRef プロトタイプオブジェクトである。

このプロパティは属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } を持つ。

26.1.3 WeakRef プロトタイプオブジェクトのプロパティ

WeakRef プロトタイプオブジェクト は次の通り:

  • %WeakRef.prototype% である。
  • その [[Prototype]] 内部スロットの値は %Object.prototype% である。
  • 通常のオブジェクトである。
  • [[WeakRefTarget]] 内部スロットを持たない。
Normative Optional

26.1.3.1 WeakRef.prototype.constructor

WeakRef.prototype.constructor の初期値は %WeakRef% である。

26.1.3.2 WeakRef.prototype.deref ( )

このメソッドは呼び出されると次の手順を実行する:

  1. weakRefthis 値とする。
  2. RequireInternalSlot(weakRef, [[WeakRefTarget]]) を実行する。
  3. WeakRefDeref(weakRef) を返す。
Note

WeakRefundefined でない target 値を返す場合、その target 値は現在の ECMAScript コードの実行が完了するまでガベージコレクションされないべきである。AddToKeptObjects 操作は読み取りの一貫性が維持されることを保証する。

let target = { foo() {} };
let weakRef = new WeakRef(target);

// ... あとで ...

if (weakRef.deref()) {
  weakRef.deref().foo();
}

上の例では、最初の deref が undefined で評価されないなら、2 回目の deref も undefined にはなり得ない。

26.1.3.3 WeakRef.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は文字列値 "WeakRef" である。

このプロパティは属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } を持つ。

26.1.4 WeakRef 抽象操作

26.1.4.1 WeakRefDeref ( weakRef )

The abstract operation WeakRefDeref takes argument weakRef (a WeakRef) and returns ECMAScript 言語値. It performs the following steps when called:

  1. targetweakRef.[[WeakRefTarget]] とする。
  2. もし targetempty でないなら
    1. AddToKeptObjects(target) を実行する。
    2. target を返す。
  3. undefined を返す。
Note

この抽象操作は、WeakRef.prototype.deref と切り離して定義されており、ライブネスを簡潔に定義できるようにしている。

26.1.5 WeakRef インスタンスのプロパティ

WeakRef インスタンスは WeakRef プロトタイプオブジェクトからプロパティを継承する通常のオブジェクトである。WeakRef インスタンスはさらに [[WeakRefTarget]] 内部スロットを持つ。

26.2 FinalizationRegistry オブジェクト

FinalizationRegistry は、ターゲットオブジェクトおよびシンボルがガベージコレクションされた際に実行されるクリーンアップ操作の登録および登録解除を管理するオブジェクトである。

26.2.1 FinalizationRegistry コンストラクタ

FinalizationRegistry コンストラクタは次の通り:

  • %FinalizationRegistry% である。
  • グローバルオブジェクト"FinalizationRegistry" プロパティの初期値である。
  • コンストラクタとして呼び出されたとき新しい FinalizationRegistry を生成し初期化する。
  • 関数として呼び出されることを意図しておらず、そのように呼び出された場合は例外を投げる。
  • クラス定義の extends 句における値として使用できる。指定された FinalizationRegistry の挙動を継承することを意図するサブクラスのコンストラクタは、FinalizationRegistry.prototype 組み込みメソッドをサポートするために必要な内部状態でサブクラスインスタンスを生成・初期化するため、FinalizationRegistry コンストラクタへの super 呼び出しを含めなければならない。

26.2.1.1 FinalizationRegistry ( cleanupCallback )

この関数は呼び出されると次の手順を実行する:

  1. もし NewTarget が undefined なら TypeError 例外を投げる。
  2. もし IsCallable(cleanupCallback) が false なら TypeError 例外を投げる。
  3. finalizationRegistry を ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationRegistry.prototype%", « [[Realm]], [[CleanupCallback]], [[Cells]] ») とする。
  4. fn をアクティブな関数オブジェクトとする。
  5. finalizationRegistry.[[Realm]]fn.[[Realm]] を設定する。
  6. finalizationRegistry.[[CleanupCallback]]HostMakeJobCallback(cleanupCallback) を設定する。
  7. finalizationRegistry.[[Cells]] に新しい空の List を設定する。
  8. finalizationRegistry を返す。

26.2.2 FinalizationRegistry コンストラクタのプロパティ

FinalizationRegistry コンストラクタは次の通り:

  • その [[Prototype]] 内部スロットの値は %Function.prototype% である。
  • 以下のプロパティを持つ:

26.2.2.1 FinalizationRegistry.prototype

FinalizationRegistry.prototype の初期値は FinalizationRegistry プロトタイプオブジェクトである。

このプロパティは属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } を持つ。

26.2.3 FinalizationRegistry プロトタイプオブジェクトのプロパティ

FinalizationRegistry プロトタイプオブジェクト は次の通り:

  • %FinalizationRegistry.prototype% である。
  • その [[Prototype]] 内部スロットの値は %Object.prototype% である。
  • 通常のオブジェクトである。
  • [[Cells]] および [[CleanupCallback]] 内部スロットを持たない。

26.2.3.1 FinalizationRegistry.prototype.constructor

FinalizationRegistry.prototype.constructor の初期値は %FinalizationRegistry% である。

26.2.3.2 FinalizationRegistry.prototype.register ( target, heldValue [ , unregisterToken ] )

このメソッドは呼び出されると次の手順を実行する:

  1. finalizationRegistrythis 値とする。
  2. RequireInternalSlot(finalizationRegistry, [[Cells]]) を実行する。
  3. もし CanBeHeldWeakly(target) が false なら TypeError 例外を投げる。
  4. もし SameValue(target, heldValue) が true なら TypeError 例外を投げる。
  5. もし CanBeHeldWeakly(unregisterToken) が false なら
    1. もし unregisterTokenundefined でないなら TypeError 例外を投げる。
    2. unregisterTokenempty に設定する。
  6. cellRecord { [[WeakRefTarget]]: target, [[HeldValue]]: heldValue, [[UnregisterToken]]: unregisterToken } とする。
  7. cellfinalizationRegistry.[[Cells]] に追加する。
  8. undefined を返す。
Note

本仕様のアルゴリズムと定義に基づくと、finalizationRegistry.[[Cells]]cell を含む間、cell.[[HeldValue]] はライブである。しかしこれは必ずしも cell.[[UnregisterToken]]cell.[[Target]] がライブであることを意味しない。例えば、あるオブジェクトをその自身を unregister token として登録しても、そのオブジェクトを永遠に生存させるわけではない。

26.2.3.3 FinalizationRegistry.prototype.unregister ( unregisterToken )

このメソッドは呼び出されると次の手順を実行する:

  1. finalizationRegistrythis 値とする。
  2. RequireInternalSlot(finalizationRegistry, [[Cells]]) を実行する。
  3. もし CanBeHeldWeakly(unregisterToken) が false なら TypeError 例外を投げる。
  4. removedfalse とする。
  5. finalizationRegistry.[[Cells]] の各 Record { [[WeakRefTarget]], [[HeldValue]], [[UnregisterToken]] } である cell について
    1. もし cell.[[UnregisterToken]]empty でなく、かつ SameValue(cell.[[UnregisterToken]], unregisterToken) が true なら
      1. cellfinalizationRegistry.[[Cells]] から除去する。
      2. removedtrue に設定する。
  6. removed を返す。

26.2.3.4 FinalizationRegistry.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% プロパティの初期値は文字列値 "FinalizationRegistry" である。

このプロパティは属性 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } を持つ。

26.2.4 FinalizationRegistry インスタンスのプロパティ

FinalizationRegistry インスタンスは FinalizationRegistry プロトタイプオブジェクトからプロパティを継承する通常のオブジェクトである。FinalizationRegistry インスタンスはさらに [[Cells]] および [[CleanupCallback]] 内部スロットを持つ。