[javascript] 자바스크립트에서의 순환 참조와 메모리 해제 방법

자바스크립트에서는 순환 참조가 발생할 수 있습니다. 순환 참조란 두 개 이상의 객체가 서로를 참조하는 상황을 말합니다. 이러한 상황에서는 사용되지 않는 메모리를 해제할 수 없어 메모리 누수가 발생합니다. 이 문제를 해결하기 위해 메모리를 해제하는 방법을 알아보겠습니다.

순환 참조의 예

다음은 순환 참조가 발생하는 예시입니다.

function Person(name) {
  this.name = name;
  this.friends = [];
}

const john = new Person('John');
const jane = new Person('Jane');

john.friends.push(jane);
jane.friends.push(john);

위 예시에서는 john 객체의 friends 배열에 jane 객체를 추가하고, jane 객체의 friends 배열에 john 객체를 추가하는 순환 참조가 발생합니다.

메모리 해제 방법

순환 참조로 인해 메모리 누수가 발생하는 경우, 가비지 컬렉터가 객체를 회수할 수 없게 됩니다. 이를 해결하기 위해서는 다음의 방법 중 하나를 사용하여 메모리를 수동으로 해제해야 합니다.

1. WeakMap이나 WeakSet 사용하기

WeakMap이나 WeakSet은 순환 참조가 발생하는 객체를 약한 참조로 저장하는 메모리 구조입니다. 이를 사용하면 가비지 컬렉터가 해당 객체를 회수할 수 있습니다.

const john = { name: 'John' };
const jane = { name: 'Jane' };

const friends = new WeakSet();
friends.add(john);
friends.add(jane);

// 객체에 대한 참조가 없는 경우, 가비지 컬렉터는 객체를 회수할 수 있음

2. 참조를 끊는 방법

순환 참조가 발생한 객체 사이에서 참조를 끊으면 가비지 컬렉터가 메모리를 회수할 수 있습니다.

function Person(name) {
  this.name = name;
  this.friends = [];
}

const john = new Person('John');
const jane = new Person('Jane');

john.friends.push(jane);
jane.friends.push(john);

// 참조를 끊어주는 코드
john.friends = null;
jane.friends = null;

위 코드에서는 john.friendsjane.friendsnull로 설정하여 순환 참조를 끊어주고, 가비지 컬렉터가 메모리를 회수할 수 있도록 합니다.

결론

자바스크립트에서 순환 참조는 메모리 누수를 발생시킬 수 있는 중요한 문제입니다. 약한 참조를 사용하거나 참조를 끊음으로써 이 문제를 해결할 수 있습니다. 메모리 관리에 주의를 기울이고, 순환 참조가 발생하지 않도록 설계하는 것이 중요합니다.


참고 자료