자바스크립트 동작원리

김철회·2022년 8월 3일
0
post-thumbnail

자바스크립트가 어떻게 동작하는지 알아보자!

자바스립트의 엔진과 브라저에서 제공하는 api를 함께 이해한다면, 자바스크립트의 동작원리에 다가설 수 있을 것이다.

자바스크립트 엔진

  • memory heap : 정보(선언한 함수나 변수)를 저장하는 공간
  • call stack : 현재 실행되고 있는 코드를 하나씩 순차적으로 실행하는 공간

자바스크립트는 기본적으로 동기 언어이다. 자바스크립트는 한 번에 여러가지를 처리하지 못한다. 하나의 한 코드만 실행할 수 있다. 그리고 이를 씽글 쓰레드(single thread)라고 한다.

위의 말을 그림으로 다시 한 번 살펴보자!
1. 기본적으로 memory heap에 저장된 선언한 함수와 변수들을 참조해서 작성한 순서대로 코드를 실행한다.
2. 실행 되는 코드들은 순차적으로 call stack에 쌓이고 순차적으로 실행이 된다.
3. 그리고 끝나면 call stack에서 제거가 된다.

위의 그림 안에 call stack에 회색 박스들이 실행할 함수들이 순차적으로 쌓여 있는 것을 나타낸 것이다.

*stackoverflow도 여기서 지어졌다고 한다. stack은 쌓다라는 의미이고 그 쌓인 게 넘쳐 흘렀다는 의미라고 한다!

아니..근데 동시에 함수가 처리되는 경우들도 있지 않아요?

순차적이라는 말은 곧 한 번에 하나를 의미한다. 하나가 끝나야만 다른 게 실행될 수 있다는 의미이다.
하지만, 자바스크립트 코드를 짜면 우리는 동시에 처리하는 경우들을 만날 수 있다. 데이터를 호출하는 ajax나, 이벤트리스너가 보통 그러하다. 이런 경우들은 도대체 무슨 사연으로 동시에 처리가 가능한 것일까?

자바스크립트 엔진의 힘만으로는 순차적인 것이 맞지만 자바스크립트는 코드를 실행 할 때, 엔진 이외에도 브라우저에서 제공하는 api도 함께 동작한다. 그리고 이 web api / event loop / callback queue에 의해서 동시성이 가능해지는 것이다.

먼저 알아두어야 하는 개념인 callback
쉽게 말해서 callback은 내가 순서를 지정하겠다는 의미이다. 코드가 작성된 순서대로 함수가 실행이 될 것이다. 하지만 내가 의도해서 순서를 정할 수 있는데 이를 callback함수라고 한다.

function A(B) {
	B();
}
function B() {
	console.log("callback이다");
}

A(callback);

만약 A와 callback 사이에 다른 함수가 있다면 순차적인 자바스크립트가 그 사이의 다른 함수를 B라는 함수보다 먼저 실행시킬 것 같지만, A함수의 인자로 B함수가 들어와 있고 A함수가 B함수를 실행 시켰기 때문에 A함수 다음에 바로 B함수가 실행될 것이다.
이처럼, callback 이란 내가 원하는대로 실행할 순서를 만들 수 있는 것이라고 생각하면 쉽다!

다시 돌아와서 자바스크립트의 엔진과 이외의 webapi가 어떻게 동작할까?

  • web api : 브라우저에서 제공하는 api로, 비동기 함수인 http 요청, setTimeout, ,이벤트리스너, Dom이벤트 등이 먼저 저장이 된다.
  • callback queue : web api에 있는 비동기 함수들이 실행되기 전에 실행 순서대로 대기를 하는 공간이다.
  • event loop : evnet loop가 지속적으로 call stack이 비어 있는지 확인한다. 그리고 call stack이 빌 때, callback queue에 순차적으로 대기중인 비동기 함수들을 call stack에 넣어 준다. 이렇게 계속 비어있는지 확인하는 것을 tick 이라고 한다.

정리! 엔진과 api가 더해져서 전체적으로 어떻게 동작하는 것일까?

> 1. 먼저 자바스크립트 엔진의 memory heap에 선언한 변수와 함수가 저장이 된다.
2. 작성된 코드를 읽고 실행하면서 순차적으로 실행할 함수들이 call stack에 쌓인다. 그리고 순차적으로 실행되면서 하나씩 완료가 되면 제거된다.
3. 그러다가 비동기 함수들이 있으면 비동기 함수들은 call stack이 아니라 브라우저에서 제공하는 webapi에 먼저 저장이 된다.
4. 실행할 순서대로 callback queue에 대기하고 있다가
5. 쌓이고 제거 되고를 반복하는 call stack이 비는 것을 event loop가 계속 확인하고 있다가 비는 순간 callback queue의 대기번호 1번 비동기함수를 실행시킨다.

메모리 관리는 어떻게 될까?

자바스크립트의 엔진에 memory heap에 선언한 변수나 함수가 저장이 된다. 하지만 저장된 변수나 함수는 웹브라우저가 실행되는 동안 내내 살아 있는 것이 아니다.

메모리 생존주기

  • 필요할 때 할당이 되고
  • 사용이 되다가
  • 필요가 없어지면 없어진다.

그렇게 메모리가 할당이 되면 call stack은 아래에서부터 실행할 코드를 하나씩 쌓고 실행하면서 memory heap에서 실행할 때 필요한 것들을 찾아서 실행한다.

Garbage Collector

하지만, memory heap과 call stack의 공간은 무제한이 아니다. 한정되어 있기 때문에 관리를 잘해야 효율성이 높아질 수 있다. 굳이 사용하지 않는 것을 저장할 필요가 없기 때문이다.
이에 따라, 자바스크립트는 더이상 필요치 않다고 판단되는 변수, 함수를 함수 실행 종류 후에 memory heap에서 제거한다. 이러한 역할을 수행하는 것을 Garbage Collector 라고 한다.

garbage collector의 알고리즘

garbage collecotr가 무엇을 하는지는 알겠는데, 어떻게 일을 하는지도 알아보자!

Mark and Sweep

이 알고리즘은 "더 이상 필요 없는 오브젝트"를 "닿을 수 없는 오브젝트"라고 정의 한다.
roots라는 오브젝트의 집합이 있는데(여기서 roots는 전역변수를 의미), 주기적으로 garbage collector는 roots로 부터 시작해서 roots가 참조하는 오브젝트들, roots가 참조하는 오브젝트가 다시 참조하는 오브젝트들을 "닿을 수 있는 오브젝트"라고 말한다. 그리고 이와 반대 개념인 닿을 수 없는 오브젝트, 그러니까 참조하지 않는 오브젝트들은 제거된다.

즉, 그 어떠한 것도 참조하지 않는 오브젝트들을 garbarge collector가 제거한다고 생각하면 된다!

profile
안녕하세요!

0개의 댓글