Javascript(2)

WorldWannyWeb.·2021년 6월 11일
0

Study

목록 보기
32/35
post-thumbnail

2021-06-10

자바스크립트에서 코드가 실행될때 어떻게 실행이 되는 것일까? 자바스크립트를 사용하면서 한번쯤 궁금했을 것이다. 한번 자바스크립트가 어떻게 돌아가는지, 거기에서 Event Loop은 어떤 역할을 하는지 구체적으로 알아보자.

1.Javascript Engine

자동차가 움직이려면 무엇이 필요할까? 너무 당연한 질문같겠지만, 당연히 기름이 필요하고, 굴러갈 바퀴도 필요할 것이다. 그치만 자동차에서 가장 핵심은 바로 엔진일 것이다. 외관이 어떻게 생겼든지간에 엔진이 없다면, 그저 자동차 모형일 뿐이다. 자바스크립트도 데이터를 받고, 코드를 실행해주는 엔진이 있다. 자바스크립트 엔진은 자바스크립트 코드를 실행하는 프로그램 혹은 인터프리터를 말하는데, 가능한 짧은 시간 내에 가장 최적화된 코드를 생성하는 것이 목표다. 표준적인 인터프리터로 구현될 수도 있고, 혹은 자바스크립트 코드를 바이트코드로 컴파일하는 JIT 컴파일러로 구현할 수도 있다. 여러 목적으로 사용될 수 있지만 주로 웹 브라우저를 위해 사용된다.V8 엔진은 구글이 만들었으며 오픈소스이고 C++로 제작되었다. 다른 엔진들과 차이점은 노드js의 런타임으로도 사용된다.

자바스크립트 엔진이 구동되면서 코드를 읽고 실행하는 과정에서 아주 중요한 두가지 단계가 있는데, ① 정보(ex. 변수, 함수 등)를 특정한 장소에 저장하는 것② 실제 현재 실행되고 있는 코드를 트래킹하는 작업이 그 두가지이다. 여기서 정보를 저장하는 공간이 바로 메모리 힙(Memory Heap)이고, 실행 중인 코드를 트래킹하는 공간이 콜 스택(Call Stack)이다.

  • Memory Heap : 변수, 함수 저장, 호출 등의 작업이 발생하는 이 공간이다. 쉽게 생각하면 'Memory Heap'이라는 이름의 창고가 있고, 변수나 함수들은 겉에 이름이 라벨지로 붙어있는 박스다.
  • Call stack : 콜스택은 메모리에 존재하는 공간 중의 하나로, 코드를 읽어내려가면서 수행할 작업들을 밑에서부터 하나씩 쌓고, 메모리 힙에서 작업 수행에 필요한 것들을 찾아서 작업을 수행하는 공간이다.
    간단한 변수들은 콜 스택에 저장되고, 객체, 배열, 함수 등 복잡한 데이터 구조의 값들은 메모리 힙에 저장된다.

Call Stack에서는 하나하나 작업이 쌓이게 되는데, 작업이 실행되고 제거가 반복된다. 하지만 작업을 수행하기 위한 또 다른 작업을 부르게 되면, 제거되지 않고, 그 위에 쌓이게 되는데 작업이 수행되지 않고 계속 쌓이게 될 경우, stack의 공간크기를 넘어서게 되는데 이것이 Stack Overflow(구글링을 하다보면 답을 찾아 자주 들어가는 사이트 이름이기도 하다)이다.

이렇게 보다보니, Call Stack과 Heap이 공간이 한정적이라는 것을 알 수 있다. 공간이 무한하지 않다보니, 효율적으로 관리해야할 필요성이 있어보인다. 이를 위해서 효용가치가 없다고 보이는 변수나 함수를 실행종료 후에 힙에서 제거하기도한다. 필요한 데이터만 힙에 저장해 여유롭게 관리하도록 하는 것이다. 이를 수행하는 도구를 Garbage Collector라고 하며, 자바스크립트는 Garbage Collected Launguage라 할 수 있다. 그렇다면 메모리관리를 안해도 되겠네? 라는 착각은 고이접어 집어넣자. 프로그램이기 때문에 완벽하지 않다.

2. Runtime

자, 엔진에 대해서 어느정도 알아보았으니 그러면 어떻게 동작이 이루어지는지도 알아보자. 자바스크립트를 이용해 코드를 만들고, 실행하면 자바스크립트 엔진에서만 모든 코드가 실행되는 것일까? v8 엔진소스를 찾아보니 그 안에 없는 함수들도 있는데 실행이 되고있는 것을 알 수 있다. 바로 예를 들면, setTimeout같은 함수다. 흔히 비동기로 동작한다고 알려져있다.

우선, 자바스크립트는 Single Thread 언어이다. Single Thread Runtime을 가지고 있다는 말인데 그말은 즉, 한번에 하나의 싱글 콜스택을 가지고 있다는 소리다. 하나의 프로그램은 하나의 코드만 실행할 수 있다는 것이다.

콜스택은 data structure로 실행되는 순서를 기억한다. 그래서 함수를 정의하고, 함수호출을 만났을때, 스택에 추가하고, 결과를 return하게 되면, 맨위에서부터 하나씩 꺼내 제거하게 됩니다. 하지만, ajax요청을 동기적으로 실행하는 while문에 넣고, 실제로 무슨일이 일어나는지 본다면, 요청을 하는동안 아무것도 클릭을 하거나 실행할 수 없다. 왜냐, 콜스택이 비어있지 않으면, 동기적으로 실행되는 네트워크 요청이 콜스택을 블로킹해 요청하는 일 외에 다른 것은 할 수 없게 만들기 때문이다. 이를 해결할 수 있는 것이 비동기 콜백이다.

자바스크립트는 하나의 일만 할 수 있지만, 동시에 일을 할 수 있는 이유는 브라우저가 webAPI를 제공해주기 때문이다. 바로 setTimeout함수같은 것을 브라우저가 제공해주는 것이다. 아래 그림을 보며 설명해보자.

API에서 제공해주는 비동기 처리 함수들이 호출이 되면 WebAPI에 들어가게 되고, 실행이 다 끝나고 나면, 그 콜백을 task Queue라는 곳에 집어넣게 된다.(위의 그림에서는 Callback Queue라고 되어있는 곳이다.) 그 사이에서 우리는 Event loop를 발견할 수 있다.

Event Loop은 이벤트가 발생하는 경우에 그에 해당하는 이벤트핸들러를 실행시켜줄 수 있게 하는 프로그램 구조인데, 여기서 엔진 안의 콜스택과 task Queue를 연결하는 역할을 한다. task Queue에 들어가있는 콜백과 스택을 주시하다가 스택이 완전히 비게 되면, 이 때 Event Loop가 task Queue에 있는 콜백을 스택에 밀어넣어준다.

profile
와니완의 월드와이드와니웹🐥

0개의 댓글