본문 바로가기
Study

[Javascript] WeakMap과 WeakSet

by 안자두 2023. 3. 6.

이전 글만 읽어서는 조금 이해가 안 되는 부분이 있어, 조금 더 찾아보았다.
그 이전 글에 대한 포스팅 👇
https://ktmihs.tistory.com/entry/article-JavaScript-Memory-Management-How-to-Avoid-Common-Memory-Leaks-and-Improve-Performance

 

[article] JavaScript Memory Management: How to Avoid Common Memory Leaks and Improve Performance

🌞 Article 👇 link https://itnext.io/javascript-memory-management-how-to-avoid-common-memory-leaks-and-improve-performance-c018dbbca954 🔥 JavaScript Memory Management: How to Avoid Common Memory Leaks and Improve Performance We will explain the memo

ktmihs.tistory.com

 

WeakMap WeakSet은 개체 및 변수에 대한 약한 참조를 만들 수 있는 특수 데이터 구조다. 약한 참조는 일반 참조와는 달리 가비지 컬렉터가 개체에서 사용하는 메모리를 해제하는 것을 막지 않는다. 
개체에 대한 참조가 약하기 때문에 가비지 컬렉터는 개체가 여전히 참조되고 있더라도 사용된 메모리를 해제할 수 있다.


우선 WeakMap은 일반 Map과는 다르게 key로 쓰인 객체가 가비지 컬렉션의 대상이 된다.
이를 위해서는 우선 WeakMap의 key는 반드시 객체여야 한다. (원시값 X)

// ===== Map() ===== 
let john = { name: "John" };

let map = new Map();
map.set(john, "...");

john = null; // 참조를 null로 덮어씀

// john을 나타내는 객체는 맵 안에 저장되어있습니다.
// map.keys()를 이용하면 해당 객체를 얻는 것도 가능합니다.
for(let obj of map.keys()){
  alert(JSON.stringify(obj));
}

// ===== WeakMap() ===== 
let john = { name: "John" };

let weakMap = new WeakMap();
weakMap.set(john, "...");

john = null; // 참조를 덮어씀

// john을 나타내는 객체는 이제 메모리에서 지워집니다!

Map에서는 key가 john을 참조하고 있기 때문에 john의 값을 불러올 수 있지만, WeakMap에서는 john이 WeakMap의 key로만 사용되기 때문에 john의 참조를 덮어쓰게 되면 가비지 컬렉터가 이를 캐치하게 된다.

그리고 Map과 WeakMap의 또 다른 차이점 중 하나는 WeakMap은 반복 작업이나 열거가 되지 않는다는 점이다.
WeakMap은 key가 가비지 컬렉터의 대상이 될 수 있기 때문에 현재 WeakMap에 요소가 몇 개 있는지 정확히 파악하는 것 자체가 불가능하다.
따라서 WeakMap은 요소 전체를 대상으로 하는 메서드는 지원하지 않고, 구성 요소 하나를 대상으로 하는 get(), set(), delete(), has() 이 네 가지의 메서드만을 제공한다.

WeakMap은 부차적인 데이터를 저장할 곳이 필요할 때 유용하게 쓰인다.
예를 들면, A라는 사람의 기본 정보가 담긴 a 객체가 있다.
이 a를 Map의 key로 사용한 후, 해당 Map에서는 A의 다른 정보를 추가적으로 저장했다.
만약 A라는 사람의 정보가 더 이상 필요 없게 될 때, a = null;하게 되면 A의 정보는 사라져야 하지만, Map에서 key로 참조하고 있기 때문에 사라지지 않는다.
이때, Map 대신 WeakMap을 사용한다면, a는 Map의 key로만 사용하기 때문에 A의 정보를 제거할 수 있게 된다.
이를 이용해 cache처럼 사용할 수도 있다.

WeakSet은 WeakMap과 유사하지만 객체만 저장할 수 있다는 점을 제외하곤 유사하다.
WeakMap이 Map의 약한 참조 버전이라면, WeakSet은 Set의 약한 참조 버전이다. WeakMap과 동일하게 요소 전체를 대상으로 하는 메서드는 지원하지 않기 때문에, 구성 요소 하나를 대상으로 하는 set(), delete(), has() 메서드를 제공한다.


https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/WeakMap

 

WeakMap - JavaScript | MDN

WeakMap 은 키에 대한 강력한 참조를 생성하지 않는 키/값 쌍의 모음으로 키는 반드시 객체이며, 값은 임의의 JavaScript 타입입니다. 강력한 참조를 생성하지 않는 이유는 객체가 WeakMap의 키로 존재

developer.mozilla.org

https://ko.javascript.info/weakmap-weakset

 

위크맵과 위크셋

 

ko.javascript.info

 

728x90