HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
👻
개발 기록
/
📚
CS 스터디
/
📚
weak map & weak set
📚

weak map & weak set

일반적인 map

  • 도달 가능한 값으로 취급되어 메모리에서 삭제되지 않습니다.
let john = { name: "John" }; let array = [ john ]; john = null; // 참조를 null로 덮어씀 // john을 나타내는 객체는 배열의 요소이기 때문에 가비지 컬렉터의 대상이 되지 않습니다. // array[0]을 이용하면 해당 객체를 얻는 것도 가능합니다. alert(JSON.stringify(array[0]));
 
이런 관점에서 위크맵(WeakMap)은 일반 맵과 전혀 다른 양상을 보입니다.
위크맵을 사용하면 키로 쓰인 객체가 가비지 컬렉션의 대상이 됩니다.
 
let john = { name: "John" }; let weakMap = new WeakMap(); weakMap.set(john, "..."); john = null; // 참조를 덮어씀 // john을 나타내는 객체는 이제 메모리에서 지워집니다!
john을 나타내는 객체는 오로지 위크맵의 키로만 사용되고 있으므로, 참조를 덮어쓰게 되면 이 객체는 위크맵과 메모리에서 자동으로 삭제됩니다.

WeapMap이란?

  • WeakMap객체는 키가 약하게 참조되는 키/값 쌍의 컬렉션으로, 키는 반드시 객체여야만 한다.
  • 원시 값은 키가 될 수 없다. 만약 키를 원시 값으로 추가하면 Uncaught TypeError: Invalid value used as weak map key라는 에러가 발생한다.
  • WeakMap은 특정 키에 대한 값이 있는지 메서드를 통해 확인 가능하지만, 키로 보유한 객체들을 열거하는 방법은 제공되지 않는다.
    • 즉, 반복 작업과 keys(), values(), entries() 메서드를 지원하지 않는다.
    • 지원하는 메서드
      • weakMap.get(key)
      • weakMap.set(key, value)
      • weakMap.delete(key)
      • weakMap.has(key)
      🚧
      clear()메서드는 보안 이슈로 인해 IE를 제외한 모든 브라우저에서 deprecated 상태.
  • 그리고 WeakMap의 키로 쓰인 객체는 가비지 컬렉션 대상이 된다.
  • 프로그램 내 객체에 대한 참조가 WeakMap을 제외하고 존재하지 않는다면, 해당 객체는 가비지로 수거된다.
 

왜 제한적일까?

→ 가비지 컬렉션의 동작 방식 때문!
  • 위 예시의 john을 나타내는 객체처럼, 객체는 모든 참조를 잃게 되면 자동으로 가비지 컬렉션의 대상이 됩니다.
  • 그런데 가비지 컬렉션의 동작 시점은 정확히 알 수 없습니다.
  • 가비지 컬렉션이 일어나는 시점은 자바스크립트 엔진이 결정합니다.
  • 객체는 모든 참조를 잃었을 때, 그 즉시 메모리에서 삭제될 수도 있고, 다른 삭제 작업이 있을 때까지 대기하다가 함께 삭제될 수도 있습니다.
  • 현재 위크맵에 요소가 몇 개 있는지 정확히 파악하는 것 자체가 불가능한 것이죠.
  • 가비지 컬렉터가 한 번에 메모리를 청소할 수도 있고, 부분 부분 메모리를 청소할 수도 있으므로 위크맵의 요소(키/값) 전체를 대상으로 무언가를 하는 메서드는 동작 자체가 불가능합니다.
 

어떤 경우에 사용할 수 있을까?

  • 객체엔 ‘주요’ 자료를, 위크맵과 위크셋엔 ‘부수적인’ 자료를 저장하는 형태로 위크맵과 위크셋을 활용할 수 있습니다.
  • 방문 횟수를 저장할 때
  • 캐싱할 때
new Map()
new Map()
new WeakMap()
new WeakMap()
 
 

WeakSet이란?

  • 위크셋은 셋과 유사한데, 객체만 저장할 수 있다는 점이 다릅니다. 원시값은 저장할 수 없습니다.
  • 셋 안의 객체는 도달 가능할 때만 메모리에서 유지됩니다.
  • 셋과 마찬가지로 위크셋이 지원하는 메서드는 단출합니다. add, has, delete를 사용할 수 있고, size, keys()나 반복 작업 관련 메서드는 사용할 수 없습니다.
let visitedSet = new WeakSet(); let john = { name: "John" }; let pete = { name: "Pete" }; let mary = { name: "Mary" }; visitedSet.add(john); // John이 사이트를 방문합니다. visitedSet.add(pete); // 이어서 Pete가 사이트를 방문합니다. visitedSet.add(john); // 이어서 John이 다시 사이트를 방문합니다. // visitedSet엔 두 명의 사용자가 저장될 겁니다. // John의 방문 여부를 확인해보겠습니다. alert(visitedSet.has(john)); // true // Mary의 방문 여부를 확인해보겠습니다. alert(visitedSet.has(mary)); // false john = null; // visitedSet에서 john을 나타내는 객체가 자동으로 삭제됩니다.
 

정리

  • WeakMap은 Map처럼 열거 메서드를 지원해주진 못하지만 참조를 약하게 유지하여 메모리 누수 관리에 메리트가 있는 자료구조이다.
  • 큰 단점은 반복 작업이 불가능하다는 점입니다. 하지만 weakmap, weakset을 이용해 할 수 있는 주요 작업을 방해하진 않습니다.
  • 사실 요즘 대부분의 프로젝트들이 프레임워크 기반으로 구현되어 일반적인 상황에서 사용할 일이 많지 않겠지만,
  • 프로젝트 내 객체를 식별자로 갖는 자료구조가 필요하다면 일반 객체나 Map을 바로 사용하기 전에 WeakMap의 사용을 한 번 고려하면 어떨까 한다.
 
 
참고자료 :
위크맵과 위크셋
WeakMap이 알고 싶다