스코프 / 가비지 컬렉터

이성은·2022년 11월 7일
0

스코프

  • 범위, 영역 즉 변수를 참조할 수 있는(= 접근할수 있는) 유효한 범위
  • 식별자(변수,함수,클래스 이름)가 유효한 범위
  • 선언된 위치에 따라 유효 범위가 결정된다.
  • 블럭 안의 변수는 블럭 안에서만 유효하다.
    그래서 이름충돌을 방지할수 있고, 메모리를 절약할수 있다.
    • 코드 블럭 : { }, if() { }, for() { }, function() { }

스코프 예시

  • 블록안에서는 상위 블록이나 전역변수를 참조할수 있다.
  • 블록 밖에서는 블록안을 참조할수 없다.
{
  const x = 1;
  {
    const y = 2;
    console.log(x); //1 
 //=> const x = 1은  전체 코드블럭에서 유효하다. 즉 상위에 블록을 참조할수 있다.
  }
  console.log(x); //1 
  // => 같은블럭이기 때문에 const x = 1; 유효하다
  console.log(y); //에러 발생 
// => 블록 밖에서는 블록 안을 참조할수 없다.
}
  • 전역 변수, 전역 스코프 (글로벌 변수, 글로벌 스코프)
  • 지역 변수(로컬변수), 지역 스코프(로컬스코프)
// 전역 변수, 전역 스코프 (글로벌 변수, 글로벌 스코프)
const text = "global"; 
{
// 지역 변수(로컬변수), 지역 스코프(로컬스코프)
  const text = "inside block1"; 
  {
    const text = "inside block2";
    console.log(text); //'inside block2'
    // => 만약 바로 상위에 없으면 더 상위를 참조
  }
}

가비지 컬렉터

  • 가비지 컬렉션 : Javascript는 엔진 내의 가비지 컬렉터(Garbage Colloector)에서 메모리 관리를 수행한다.
  • 자바스크립트 엔진 내에선 가비지 컬렉터(garbage collector)가 끊임없이 동작. 가비지 컬렉터는 모든 객체를 모니터링하고, 도달할 수 없는 객체는 삭제

가비지 컬렉션 기준

  • 자바스크립트는 도달 가능성(reachability) 이라는 개념을 사용해 메모리 관리를 수행
  • 루트(Root) : 태생부터 도달이 가능하여 명백한 이유없이는 삭제된지 않는 값
    • 현재 함수의 지역변수와 매개변수
    • 중첩 함수의 체인에 잇는 함수에서 사용되는 변수와 매개변수
    • 전역 변수와
    • 기타 등등
    • 루트가 참조하는 값이나 체이닝으로 루트에서 참조할 수 있는 값은 도달 가능한 값이다.

내부 알고리즘, 가비지 컬렉션 기본 알고리즘('mark-and-sweep’)

  • 루트(Root)에 접근하여 Mark한다.
  • 루트 참조하는 객체에 접근하여 Mark한다.
  • 더이상 참조하는 객체가 없을 때까지 객체가 참조하는 객체에 접근하여 Mark한다.
  • 더이상 접근할 객체가 없으면, Mark되지 않은 객체를 메모리에서 삭제(Sweep)한다.
    ※ 중요한 점은, 루트를 출발지로해서 참조가 되어 도달 가능한 객체여야 삭제가 안된다는 점이다. 루트가 접근할 수 없고 지들끼리 참조하는 객체 덩어리를 "도달할 수 없는 섬(Unreachable Island)"이라고 한다.

GC 최적화 기법

  • generational collection(세대별 수집) : 오래된 객체와 새로운 객체를 구분하여, 새로운 객체는 엄격하게 감시하여 제거하고 오래된 객체는 덜 감시함.
  • incremental collection(점진적 수집) : 방문해야할 객체가 많으면 부하가 높아진다. 모든 객체를 한번 다 방문하지말고, 여러부분으로 나누어 점진적으로 GC를 진행한다. 그 차이로 인한 변경사항을 추적하는데 추가작업이 필요하다.
  • idle-time collection(유휴 시간 수집) : CPU 부하를 덜 주기위하여, idle 상태에서만 GC를 실행함.

가비지 컬렉터 예시

// 글로벌 변수는 앱이 종료될때까지 계속 메모리에 유지됨!
// => 이름 충돌과 메모리 측면에서도 좋지 않다.
// => 변수는 가급적 변수는 필요한 곳에서 선언해서 쓰는게 좋다.
const global = 1;
{
  // 블럭 내부에서만 존재하고, 블럭이 끝나면 자동으로 소멸됨 (GC)
  const local = 1;
}

function print() {
  // 함수 내부에서도 블럭안에서 필요한 경우에는
  // 필요한 곳에서! 블럭 안에서 변수를 선언하고 사용해야 함
  if (true) {
    let temp = 0;
  }
}

TIL

💡 즉 변수는 최대한 필요한 곳에서 정의해야 한다! 💡

profile
함께 일하는 프론트엔드 개발자 이성은입니다🐥

0개의 댓글