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 생성자는:

  • 값이 %Function.prototype%[[Prototype]] 내부 슬롯을 가진다.
  • 다음 속성들을 가진다:

26.1.2.1 WeakRef.prototype

WeakRef.prototype의 초기값은 WeakRef 프로토타입 객체이다.

이 속성은 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 속성 특성을 가진다.

26.1.3 WeakRef 프로토타입 객체의 속성

WeakRef 프로토타입 객체는:

  • %WeakRef.prototype%이다.
  • 값이 %Object.prototype%[[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로 평가되지 않으면 두 번째 deref도 그렇게 평가될 수 없다.

26.1.3.3 WeakRef.prototype [ %Symbol.toStringTag% ]

%Symbol.toStringTag% 속성의 초기값은 String 값 "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 an ECMAScript language value. It performs the following steps when called:

  1. targetweakRef.[[WeakRefTarget]]이라고 하자.
  2. targetempty가 아니면,
    1. AddToKeptObjects(target)를 수행한다.
    2. target을 반환한다.
  3. undefined를 반환한다.
Note

추상 연산은 liveness를 간결하게 정의할 수 있게 하기 위해서만 WeakRef.prototype.deref와 별도로 정의된다.

26.1.5 WeakRef 인스턴스의 속성

WeakRef 인스턴스는 WeakRef 프로토타입 객체로부터 속성을 상속하는 보통 객체이다. WeakRef 인스턴스는 또한 [[WeakRefTarget]] 내부 슬롯을 가진다.

26.2 FinalizationRegistry 객체

FinalizationRegistry는 대상 객체와 심벌이 가비지 컬렉션될 때 수행되는 cleanup 연산의 등록과 등록 해제를 관리하는 객체이다.

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. fnactive function object라고 하자.
  5. finalizationRegistry.[[Realm]]fn.[[Realm]]으로 설정한다.
  6. finalizationRegistry.[[CleanupCallback]]HostMakeJobCallback(cleanupCallback)으로 설정한다.
  7. finalizationRegistry.[[Cells]]를 새로운 빈 List로 설정한다.
  8. finalizationRegistry를 반환한다.

26.2.2 FinalizationRegistry 생성자의 속성

FinalizationRegistry 생성자는:

  • 값이 %Function.prototype%[[Prototype]] 내부 슬롯을 가진다.
  • 다음 속성들을 가진다:

26.2.2.1 FinalizationRegistry.prototype

FinalizationRegistry.prototype의 초기값은 FinalizationRegistry 프로토타입 객체이다.

이 속성은 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } 속성 특성을 가진다.

26.2.3 FinalizationRegistry 프로토타입 객체의 속성

FinalizationRegistry 프로토타입 객체는:

  • %FinalizationRegistry.prototype%이다.
  • 값이 %Object.prototype%[[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]]live이다. 그러나 이것이 반드시 cell.[[UnregisterToken]] 또는 cell.[[Target]]live임을 의미하지는 않는다. 예를 들어, 객체를 자기 자신을 unregister token으로 하여 등록한다고 해서 그 객체가 영원히 live 상태로 유지되지는 않는다.

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% 속성의 초기값은 String 값 "FinalizationRegistry"이다.

이 속성은 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } 속성 특성을 가진다.

26.2.4 FinalizationRegistry 인스턴스의 속성

FinalizationRegistry 인스턴스는 FinalizationRegistry 프로토타입 객체로부터 속성을 상속하는 보통 객체이다. FinalizationRegistry 인스턴스는 또한 [[Cells]][[CleanupCallback]] 내부 슬롯을 가진다.