자바스크립트는 눈에 보이지 않는 곳에서 메모리 관리를 진행하는데, 코드를 작성하다가 더 이상 쓸모없어진 것들이 발생하면 어떻게 처리되는 걸까?
쓸모 없어진 객체가 차지하는 메모리를 자동으로 해제하는 것을 말한다.
자바스크립트에서 가비지 컬렉션은 도달 가능성
의 개념을 통해 메모리 관리를 진행한다.
root
의 값👇 아래와 같은 객체가 있다고 하자.
let seohee = {
hobby : "dance",
age : 24
};
여기서 객체에 null을 할당하면,
seohee = null;
console.log(seohee); // undefined
객체에 도달할 수 없는 상태가 된다.
하지만, 원본 객체의 메모리를 해제하기 전에 참조할 객체를 만들어주고, 메모리를 해제한다면,,,!
let cloneSeohee = seohee;
seohee = null;
console.log(seohee); // undefined
console.log(cloneSeohee); // {hobby: 'dance', age: 24}
원본 객체로는 참조가 불가능하지만, 새로 생성된 객체에서는 여전히 참조가 가능하다.
function transaction(seller, buyer) {
seller.receive = buyer;
buyer.giveAway = seller;
return {
구매자: buyer,
판매자: seller
}
}
let 고데기 = transaction({
name: "seohee"
}, {
name: "nayeon"
});
transaction(거래) 함수는 매개변수로 받은 두 객체를 서로 참조하여 거래시킨다.
현재 고데기 상품을 통해 모든 객체에 도달 가능하다.
👇 여기서 참조 두 개를 삭제해보자.
delete 고데기.구매자;
delete 고데기.판매자.receive;
고데기.판매자에만 접근할 수 있다.
console.log(고데기.판매자); // seohee
만약, 함수 전체에 null을 할당하면,
transaction = null;
도달할 수 없는 섬이 만들어진다.
자바스크립트 엔진에서 가비지 컬렉터가 수행하는 내부 알고리즘을 mark-and-sweep이라고 한다.
도달 가능한 객체를 마크(mark)
하고 그 외의 값은 제거(sweep)
하는 개념이다.
가비지 컬렉터는 루트(root) 정보를 수집하고 이를 mark(기억)
루트가 참조하고 있는 모든 객체를 방문하고 이것들을 mark
mark 된 모든 객체에 방문하고 그 객체들이 참조하는 객체도 mark
한번 방문한 객체는 전부 mark 하기 때문에 같은 객체를 다시 방문하는 일은 없다.
루트에서 도달 가능한 모든 객체를 방문할 때까지 위 과정을 반복한다.
mark 되지 않은 모든 객체를 메모리에서 삭제한다.
👇 결과를 그림으로 나타내면 다음과 같다.
빨간 테두리는 도달이 불가능 하기때문에 가비지 컬렉터에 의해 제거된다.
가비지 컬렉션의 동작 방식은 브라우저의 자바스크립트 엔진에 따라 다르지만 2012년 기준으로 모든 최신 브라우저들은 가비지 컬렉션에서 mark-and-sweep 알고리즘을 사용한다.
📚 학습할 때, 참고한 자료 📚