메모리 누수란?
: 부주의 또는 일부 프로그램의 오류로 더이상 사용되지 않는 메모리를 해제하지 못하는 것
즉, 사용하지도 않는 데 자리만 차지하고 있는 메모리를 말한다. (자리 도둑)
JS의 메모리
- 스택(Stack) 메모리 : 단순 변수(String, Number, Boolean, Null, Undefined, Symbol, Bight)
- 힙(Heap) 메모리 : 참조 데이터 타입(Object, Array, Function)
JS의 메모리 관리
C언어와 같은 저수준 언어에서는 메모리 관리를 위해 malloc()과 free()를 사용하지만,
JS는 객체가 생성(선언) 되었을 때 자동으로 메모리를 할당하고, 쓸모 없어졌을 때(더이상 사용하지 않을 때) 자동으로 해제한다. (가비지 컬렉터)
이러한 자동 메모리 관리는 개발자가 메모리 관리에 대해 고민할 필요가 없다는 잘못된 인식(인상)을 주기 때문에 잠재적 혼란의 원인이 된다.
메모리의 생존 주기
- 필요할 때 할당한다.
- 사용한다. (읽기, 쓰기)
- 필요 없으면 해제한다(지운다).
가비지 컬렉터(Garbage Collection)이란?
프로그램을 개발하다 보면 유효하지 않은 메모리인 가비지(Garbage)가 발생한다.
C언어를 이용하면 free()라는 함수를 통해 직접 메모리를 해제 해주어야 하지만 Java나 Kotlin을 이용하면
개발자가 메모리를 직접 해제 해주는 일이 없다. 그 유이는 JVM의 가비지 컬렉터가 불필요한 메모리를 알아서 정리 해주기 때문이다. 대신 Java에서는 명시적으로 불필요한 데이터를 표현하기 위해서 일반적으로 null을 선언한다.
예를 들어 아래와 같은 코드가 있다고 가정 했을 때
Person person = new Person();
person.setName("Mang");
person = null;
// 가비지 발생
person = new Person();
person.setName("MangKyu");
출처: https://mangkyu.tistory.com/118 [MangKyu's Diary:티스토리]
Mang이라는 값을 기본값으로 가진 person 객체는 더이상 참조를 하지 않고 사용이 되지 않기 때문에 가비지(Garbage)가 되었다. 위에서 언급 했듯이 Java나 Kotlin에서는 이러한 메모리 누수를 방지하기 위해 가비지 컬렉터(Garbage Collection)이 주기적으로 검사하여 메모리를 청소 해준다.
(Java에서도 System.gc()를 이용해 호출 할 수 있지만, 해당 메소드를 호출하는 것은 시스템의 성능에 매우 큰 영향을 미치기 때문에 절대 호출하면 안된다고 한다.)
메모리 누수의 대표적인 예시
1. 클로저의 잘못된 사용
2. 의도치 않게 생성된 전역변수
: 일반적으로 전역변수는 가비지 컬렉터의 대상이 되지 않는다. 그러나 자바스크립트에서는 아래 예시처럼 정의하지 않은 변수에 값을 할당하면 전역변수에 값을 할당하는 것처럼 작동하기 때문에 의도치 않게 생성된 전역변수는 가비지 컬렉터의 대상이 되지 않아 메모리 누수의 원인으로 이어진다.
3. 분리된 DOM 노드
4. 콘솔 출력
: 개발 환경일 때 디버그 목적으로 콘솔을 출력 할 수 있다. 하지만 실제 프로덕션 환경에서는 가능한 콘솔에 데이터를 출력하지 않는 것이 좋다. 콘솔 출력은 출력하고자 하는 정보를 브라우저에 저장하기 때문에 메모리 누수에 원인이 된다.
5. 해제하지 않은 타이머
: 사용 용도, 상황에 따라 적절히 타이머를 해제 시켜주지 않는 경우 메모리를 계속 점유하고 있어 메모리 누수의 원인이 된다.
스터디 하면서 메모리 누수에 대한 글을 공유 받았는 데.. 기존 코딩 스타일 자체가 console 찍는 걸 안좋아 해서 글을 읽으면서도 괜찮게 프로젝트를 진행하고 있구나 느꼈지만.. API 호출 할 때 찍은 console.error가 생각났다. 더 좋은 방법을 구안 해봐야 할 것 같다.
'더 알아보기 > 개념' 카테고리의 다른 글
애자일(Agile) 방법론 (0) | 2023.03.24 |
---|---|
CSS 모듈화 (0) | 2022.07.13 |
EJS Include란? (0) | 2022.03.01 |
EJS란? (0) | 2022.03.01 |
Git fork vs clone (0) | 2022.02.05 |
댓글