메모리 누수: Garbage Collection, 전역 변수, 브라우저에서 메모리 확인하기

2023. 2. 15. 12:52Computer Science

728x90
반응형

메모리 누수

Garbage Collection

변수를 만들면 변수를 브라우저 메모리에 저장하고,
만든 변수들 중 필요 없는 것들은 모아뒀다가 한번에 지운다.
👉🏻 GC(Garbage Collector)가 Garbage Collection을 하는 것이다.

 

JS나 Java 같은 대부분의 언어는 메모리를 자동으로 할당해주는데,
C언어 등의 일부 언어는 메모리를 직접 할당하고 데이터를 저장해야 한다.

 

JavaScript는 GC가 해주니까 따로 메모리 관리를 할 필요는 없지만, 잘못 알게되면 문제가 생길 수 있다.
컴퓨터가 똑똑하긴 하지만 신은 아니니까! 컴퓨터가 오해를 하게 코딩을 하게되면, Garbage Collection을 해도 깔끔하게 지워지지 않을 수 있다.

 

아래는 잘 지워지고 있는 상태이다.

 

Garbage Collector가 수거하는 알고리즘에는 여러가지가 있는데,
JS에서는 대표적으로 Mark & Sweep이 있다.

 

Mark & Sweep

사용하지 않는 변수에 marking을 해두고 메모리가 차면 마킹해둔 애들을 한번에 지운다.
지우는 텀이 길면 지울 것이 많아서 잠깐씩 멈추는 현상이 있을 수 있다.
ex) 게임 하다가 잠깐씩 멈추는 현상은, Garbage Collector가 돌고 있어서일 수 있다!

 

메모리 누수

변수를 잘못 사용해서 메모리 누수가 발생할 수 있다.
GC가 마크를 못할 경우인데, 이럴 경우 메모리가 아래와 같이 나타난다.

위처럼 지속해서 누수가 발생하면
더이상 변수를 저장할 데가 없어져서 컴퓨터가 죽는다!

 

👇🏻 프론트 컴퓨터(브라우저) 죽었을 때 화면

 

👇🏻 서버 컴퓨터(Node) 죽었을 때 화면

전역 변수

이런 문제를 발생시키는 경우는 어떤 것이 있을까?

Closure, 전역 변수 등의 사례가 있다.
클로져는 브라우저 개선으로 거의 문제가 없어졌지만, 전역 변수는 여전히 신경써줘야 한다!!!

1. 전역 변수를 잘못 쓴 사례를 보자!

box 변수가 전역 변수로 선언되어 사라지지 않고 계속해서 메모리를 차지하고 있다.
box는 전역변수이기 때문에 어디서든 접근할 수 있어서, GC가 마킹하지 못해 지워지지 않는다.

const box = [];
const start = () => {
  for (let i = 0; i <= 1000000; i++) {
    box[String(Math.random())] = "철수";
  }
};

계속해서 메모리가 올라가고 있다.


2. 전역 변수를 지역 변수로 변경해보자

함수 안으로 box 변수를 옮기면 start 함수가 종료되면 필요가 없어져 마킹이 되고 사라지게 된다.

const start = () => {
  const box = [];
  for (let i = 0; i <= 1000000; i++) {
    box[String(Math.random())] = "철수";
  }
};


3. 변수를 비워주는 로직을 추가해보자

box 변수를 비워주는 로직을 추가하는 방법도 있다.

const del = () => {
  box = null;
};

 

브라우저에서 메모리 확인하기

1) 그래프 확인

  1. 개발자 도구 > Performance 탭으로 들어간다.
  2. Memory 체크 ㄱㄱ
  1. Record 버튼 ⚪️을 눌러서 메모리 점유량을 녹화할 수 있다.
  2. Collect Garbage 🗑을 누르면 GC가 실행되어 마킹된 변수들이 지워진다.
  3. 그래프로 확인 가능~!

2) Heap Snapshots 찍기

  1. 개발자 도구 > Memory 탭으로 들어간다.
  2. Take heap snapshot 버튼 ⚪️을 눌러서 스냅샷을 찍는다.
  3. Statistics로 변경하면 그래프로 볼 수 있다.

728x90
반응형