/Development/JavaScript

Closure가 메모리를 유지하는 방식


JavaScript를 어느 정도 학습하다 보면 반드시 만나게 되는 개념이 Closure입니다.
초급 단계에서는 단순히 "함수가 자신이 선언된 환경을 기억하는 것" 정도로 설명되지만,
실제로 Closure는 JavaScript의 메모리 관리와 매우 깊은 관련이 있습니다.

많은 개발자들이 Closure 문법 자체는 이해하지만
왜 함수가 종료된 이후에도 특정 변수에 접근할 수 있는지,
어떻게 메모리가 유지되는지에 대해서는 정확히 알지 못하는 경우가 많습니다.

Closure를 제대로 이해하면 상태 관리,
모듈 패턴,
이벤트 처리,
비동기 프로그래밍 등 다양한 영역에서 더욱 효율적인 코드를 작성할 수 있습니다.

특히 React를 비롯한 현대 프론트엔드 프레임워크에서도 Closure는 매우 중요한 역할을 수행합니다.

따라서 Closure를 단순한 면접 질문이 아니라
JavaScript 동작 원리를 이해하기 위한 핵심 개념으로 접근하는 것이 중요합니다.

Closure란 무엇인가

Closure는 함수가 생성될 당시의 외부 변수 환경을 기억하는 특성을 의미합니다.

일반적으로 함수가 종료되면 내부에서 사용하던 지역 변수들도 함께 사라질 것이라고 생각하기 쉽습니다.
하지만 특정 상황에서는 함수가 종료된 이후에도 변수들이 계속 유지됩니다.

그 이유는 JavaScript 엔진이 해당 변수가 앞으로도 사용될 가능성이 있다고 판단하기 때문입니다.

즉 함수가 자신이 선언된 스코프의 변수들을 참조하고 있다면
엔진은 해당 데이터를 메모리에서 제거하지 않습니다.

이러한 현상을 Closure라고 부릅니다.

Closure는 함수와 그 함수가 접근할 수 있는 렉시컬 환경(Lexical Environment)의 조합으로 정의됩니다.

결국 Closure는 단순한 문법 기능이 아니라
함수와 메모리의 관계를 설명하는 중요한 개념이라고 볼 수 있습니다.

렉시컬 스코프와 Closure의 관계

Closure를 이해하기 위해서는 렉시컬 스코프를 먼저 알아야 합니다.

JavaScript는 함수를 어디서 호출했는지가 아니라
어디에서 선언했는지를 기준으로 변수 접근 범위를 결정합니다.

이를 렉시컬 스코프라고 부릅니다.

함수가 생성되는 순간 주변 환경 정보가 함께 저장되며
이 정보는 함수가 실행되는 시점까지 유지됩니다.

따라서 함수가 다른 곳으로 전달되거나 반환되더라도
원래 선언된 위치의 변수들을 계속 참조할 수 있습니다.

Closure는 바로 이러한 렉시컬 스코프 구조 위에서 동작합니다.

즉 Closure를 이해한다는 것은 JavaScript의 변수 탐색 방식 자체를 이해하는 것과 같습니다.

함수가 종료되어도 변수가 사라지지 않는 이유

일반적으로 함수 실행이 종료되면
함수 내부의 지역 변수는 더 이상 필요하지 않으므로 제거됩니다.

하지만 내부 함수가 외부 함수의 변수를 참조하고 있는 경우 상황이 달라집니다.

JavaScript 엔진은 해당 변수가 앞으로도 사용될 수 있다고 판단합니다.

그 결과 변수는 메모리에 계속 남아 있게 됩니다.

이 과정에서 외부 함수의 실행 컨텍스트는 종료되지만
참조 중인 데이터는 별도로 보존됩니다.

즉 Closure가 형성되면 필요한 데이터만 선택적으로 살아남게 됩니다.

이것이 함수가 종료된 이후에도 특정 값을 기억할 수 있는 이유입니다.

결국 Closure는 메모리를 유지하는 특수한 메커니즘이라고 볼 수 있습니다.

Closure가 메모리를 저장하는 방식

JavaScript 엔진은 함수를 생성할 때
현재 스코프에 대한 참조 정보를 함께 저장합니다.

이를 Environment Reference라고 부르기도 합니다.

함수 내부에서 외부 변수를 사용한다면
엔진은 해당 변수에 대한 연결 정보를 유지합니다.

중요한 점은 전체 스코프를 모두 저장하는 것이 아니라
실제로 참조하는 데이터만 유지한다는 것입니다.

이를 통해 불필요한 메모리 사용을 최소화합니다.

Closure가 생성되면 관련 데이터는 힙 메모리 영역에 저장되며
참조가 존재하는 동안 제거되지 않습니다.

따라서 함수가 계속 살아 있는 한
연결된 데이터 역시 메모리에 남아 있게 됩니다.

Garbage Collection과 Closure의 관계

JavaScript에는 자동 메모리 관리 시스템인 Garbage Collection이 존재합니다.

Garbage Collector는 더 이상 사용되지 않는 객체를 찾아 제거합니다.

하지만 Closure에 의해 참조 중인 데이터는 사용 중인 것으로 판단됩니다.

따라서 Garbage Collector는 해당 데이터를 삭제하지 않습니다.

이것이 Closure가 메모리를 유지할 수 있는 핵심 이유입니다.

반대로 Closure를 사용하는 객체가 더 이상 참조되지 않는다면
관련 데이터 역시 함께 정리됩니다.

즉 Closure가 있다고 해서 영구적으로 메모리가 유지되는 것은 아닙니다.

참조 관계가 끊어지는 순간 Garbage Collector가 정상적으로 메모리를 회수하게 됩니다.

Closure가 실무에서 사용되는 이유

실제 개발 환경에서는 Closure가 매우 자주 활용됩니다.

대표적인 사례 중 하나는 데이터 은닉입니다.
외부에서 직접 접근할 수 없는 값을 Closure 내부에 보관할 수 있습니다.

또한 상태 관리 기능을 구현할 때도 많이 사용됩니다.
특정 변수의 값을 계속 기억하면서 업데이트해야 하는 경우 Closure가 적합합니다.

이벤트 핸들러에서도 Closure는 중요한 역할을 수행합니다.
버튼 클릭 이벤트가 발생했을 때 과거 상태를 기억해야 하는 상황이 많기 때문입니다.

React Hook 또한 내부적으로 Closure 특성을 적극 활용합니다.

따라서 Closure는 단순한 이론이 아니라 실무 개발의 핵심 기술 중 하나라고 할 수 있습니다.

Closure 사용 시 주의해야 할 점

Closure는 강력한 기능이지만 잘못 사용하면 메모리 문제가 발생할 수 있습니다.

불필요하게 큰 객체를 Closure가 참조하고 있다면
해당 데이터가 계속 메모리에 남게 됩니다.

특히 오래 유지되는 이벤트 리스너나 전역 객체와 함께 사용될 경우
예상하지 못한 메모리 누수가 발생할 수 있습니다.

대규모 애플리케이션에서는 이러한 문제가 성능 저하로 이어질 수 있습니다.

따라서 Closure를 사용할 때는 실제로 필요한 데이터만 참조하도록 설계하는 것이 중요합니다.

또한 사용이 끝난 객체는 참조를 제거하여 Garbage Collection이 정상적으로 동작할 수 있도록 해야 합니다.

Closure의 장점을 활용하면서도 메모리 관리에 대한 이해를 함께 갖추는 것이 중요합니다.

Summary

Closure

• 함수가 생성될 당시의 외부 환경을 기억하는 기능.
• 함수 종료 이후에도 특정 변수에 접근 가능함.
• 렉시컬 스코프를 기반으로 동작함.
• 상태 관리와 데이터 은닉 구현에 자주 사용됨.

Memory Management

• Closure가 참조하는 데이터는 메모리에 유지됨.
• Garbage Collector는 참조 중인 데이터를 제거하지 않음.
• 참조가 끊어지면 자동으로 메모리가 회수됨.
• 잘못 사용하면 메모리 누수가 발생할 수 있음.


블로그 목록