26 메모리 관리 (Managing Memory)

26.1 WeakRef 객체

WeakRef 는 대상 객체나 심볼을 가비지 컬렉션으로부터 유지하지(보호하지) 않은 채로 참조하기 위해 사용되는 객체이다. WeakRef 는 대상이 아직 가비지 컬렉션에 의해 회수되지 않았다면 대상 값에 접근할 수 있도록 역참조(dereference)될 수 있다.

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 값을 반환한다면, 현재 ECMAScript 코드 실행이 완료될 때까지 이 target 값은 가비지 컬렉션되지 않아야 한다. AddToKeptObjects 연산이 읽기 일관성이 유지되도록 보장한다.

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

// ... later ...

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

위 예에서 첫 번째 deref 가 undefined 로 평가되지 않는다면 두 번째 deref 또한 undefined 가 될 수 없다.

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. target = weakRef.[[WeakRefTarget]].
  2. targetempty 가 아니면
    1. AddToKeptObjects(target) 수행.
    2. target 반환.
  3. undefined 반환.
Note

이 추상 연산은 liveness 를 간단히 정의할 수 있도록 WeakRef.prototype.deref 와 분리되어 정의된다.

26.1.5 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. fn = 활성 함수 객체로 둔다.
  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. unregisterToken = empty 로 설정.
  6. cell = Record { [[WeakRefTarget]]: target, [[HeldValue]]: heldValue, [[UnregisterToken]]: unregisterToken }.
  7. finalizationRegistry.[[Cells]]cell 추가.
  8. undefined 반환.
Note

명세의 알고리즘과 정의에 따르면 finalizationRegistry.[[Cells]]cell 을 포함하는 동안 cell.[[HeldValue]]live 이다; 그러나 이것이 반드시 cell.[[UnregisterToken]] 또는 cell.[[Target]]live 임을 의미하지는 않는다. 예를 들어 객체를 자기 자신을 unregister token 으로 하여 등록해도 그 객체를 영원히 살려 두지 않는다.

26.2.3.3 FinalizationRegistry.prototype.unregister ( unregisterToken )

이 메서드는 호출 시 다음 단계를 수행한다:

  1. finalizationRegistrythis 값으로 둔다.
  2. RequireInternalSlot(finalizationRegistry, [[Cells]]) 수행.
  3. CanBeHeldWeakly(unregisterToken) 이 false 이면 TypeError 예외.
  4. removed = false 로 둔다.
  5. finalizationRegistry.[[Cells]] 의 각 Record { [[WeakRefTarget]], [[HeldValue]], [[UnregisterToken]] } cell 에 대해
    1. cell.[[UnregisterToken]]empty 가 아니고 SameValue(cell.[[UnregisterToken]], unregisterToken) = true 이면
      1. finalizationRegistry.[[Cells]] 에서 cell 제거.
      2. removed = true 로 설정.
  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 프로토타입 객체로부터 프로퍼티를 상속하는 일반 객체이다. 또한 [[Cells]][[CleanupCallback]] 내부 슬롯을 가진다.