자바스크립트 .00 자바스크립트?

이번 글에서는 자바스크립트의 전반적인 이야기와 작동방식 등을 알아보고자 합니다.
어떻게 코드가 브라우저에서 돌아가나 알아봅시다.

JavaScript?!


과거 웹 브라우저 시장을 지배하고 있던 넷스케이프는 정적인 HTML을 동적으로 표현하기 위에 간단한 프로그래밍 언어를 도입하기로 결정했고, 탄생한 것이 바로 자바스크립트입니다.

원래는 Mocha라는 이름으로 있다가 LiveScript를 거쳐 JavaScript라는 이름이 되었습니다. 자바스크립트는 엉망진창인 언어입니다. 브라우저마다 호환되는 것도 다르며, 명확한 기준도 없었습니다. 사실 있었지만 자사 브라우저가 기준이 되고 싶은 욕심에 잘 지켜지지 않았죠. 최근 구글 크롬이 사용하는 V8엔진의 점유율이 높아져서 V8엔진 기준으로 많이 맞춰지고 있는거 같긴합니다. 그래서 빠르게 변화하고 발전하고 있는 영역이 바로 "Front" 영역이 아닐까 생각합니다.

프로그래밍에서는 일반적으로 두가지 번역 방식을 사용하고 있습니다.
바로 인터프리터컴파일러입니다.
인터프리터는 코드를 한줄 한줄 순차적으로 변환하는 방식으로 코드를 실행하기 전 컴파일 단계가 없기 때문에 실행속도는 빠르지만 같은 코드를 두 번 이상 실행 할 경우 최적화가 되어 있지 않아 반복 적인 똑같은 함수 호출은 결과적으로 속도에서 손해가 발생합니다.
컴파일러는 시작하기전 컴파일이라는 과정을 거치기 때문에 실행하기까지 시간이 조금 더 걸리지만 코드를 실행할 때마다 번역할 필요가 없어져서 반복적으로 똑같은 함수를 호출할 때 이미 단순화 덕분에 불필요한 작업을 거치지 않게 됩니다.

그럼 자바스크립트는 어떻게 작동하는 걸까요?

자바스크립트 런타임(JavaScript Runtime)


자바스크립트는 하나의 콜스택을 가지는 single thread 프로그래밍 언어 입니다.
싱글 쓰레드라는 것은 한 번에 하나의 명령만 실행되는 것을 의미합니다. 따라서 자바스크립트는 동기식(Synchronous)으로 작업을 처리할 수 밖에 없는데, 만약 처리하는데 많은 시간이 걸리는 작업을 하게 되면 그 작업을 처리하는 동안은 사용자는 아무것도 할 수 없게 되버립니다. 이를 해결하고자 오래 걸리는 작업은 백 그라운드에서 처리하고 금방 처리할 수 있는 작업만 콜스택에서 처리하고자 한다면, 효율적으로 처리할 수 있을 겁니다. 바로 이런 일을 가능하게 해주는 것이 자바스크립트 런타임입니다.

콜 스택과 메모리힙


인터프리터 방식을 사용하는 자바스크립트가 데이터는 어디에 저장하고, 현재 어느 부분을 실행하고 있는지를 어떻게 알 수 있을까요?
여기서 콜 스택과 메모리힙의 역할을 알 수 있습니다.
콜 스택은 실행한 코드를 쌓아 위에서 부터 순차적으로 실행시킵니다.

function add(num1,num2){
  return num1+num2;
}

function mul(num1,num2){
  return num1*num2; 
}

function calculate(type,num1,num2){
  if (type==="add"){
  	const result = add(num1,num2)
    console.log(result)
  }else if (type==="mul"){
    const result = mul(num1,num2)
    console.log(result)
  }else{
    return console.log("Not found type")
  }  
}

calculate("add",1,2)

콜 스택에 먼저 calculate("add",1,2) 가 들어갑니다.
이후 add(num1,num2)가 위에 쌓이고, add 함수는 호출 되어 사라지고 console.log(result)가 위에 쌓였다가 호출 되며 콘솔에 나타납니다. 그리고 calculate("add",1,2)도 실행이 끝나면 사라지며 콜스택은 비어있게 됩니다.

const number = 112;
const name = 'Chanho'
const food = {
	first : 'meet'
	last: 'fish'
}

메모리힙에는 위와 같은 변수나 객체를 저장합니다.

스택오버플로우(Stack Overflow)


콜 스택과 메모리힙은 무적이 아닙니다. 즉, 용량이 무한하지 않습니다.
그래서 스택오버플로우라는 오류가 발생할 수 있습니다. 이 말은 용량 사이즈를 초과했다. 라는 의미입니다. 만약 반복이나 재귀함수로 계속해서 콜 스택에 스택이 쌓이기만 한다면 용량을 초과하게 될테고 브라우저는 오류를 발생시키고 함수를 종료시킵니다.

메모리 누수(Memory Leak)


메모리힙도 용량이 한정적이기 때문에 이를 초과하면서 데이터를 저장하게 될 때 메모리 누수라고 하는 문제가 발생합니다. 참조는 되고 있지만 쓰지 않는 데이터가 많다면 가비지 컬렉터가 지우지 못하고 계속해서 메모리를 낭비하기 때문에 이런 문제가 발생할 수 있습니다.

  1. 전역변수를 많이 만든다.
  2. 이벤트 리스너

    이벤트 리스너는 특정상황에 실행되기 때문에 항상 대기하며 기다리고 있어 메모리를 차지하고 있습니다.

가비지 컬렉터(Garbage Collector)


앞서 언급된 가비지 컬렉터는 사용하지 않는 변수나 함수를 종료 후에 메모리에서 제거하는 역할을 합니다. 즉, 현재 사용하고 있는 필요한 데이터만 남기고 제거해서 메모리의 여유 용량을 확보합니다.

Web API


Web API는 브라우저와 함께 제공되며, HTTP전송, setTimeout, DOM Event 등과 같은 다양한 작업을 수행할 수 있다. 또한 브라우저에서 캐싱, 데이터베이스 저장소를 사용할 수 있게 해준다.

개발자 도구에 들어가서 콘솔창에 window를 입력해보면 엄청나게 방대한 양의 객체가 나오는 것을 확인할 수 있는데, 이 window객체가 바로 브라우저에서 제공하는 Web API이다.

Web API를 사용하여 백그라운드에서 비동기적으로 작업을 처리할 수 있고, 작업이 끝나면 자바스크립트 엔진(콜 스택)에게 해당 작업이 끝났음을 알리고 계속해서 작업을 수행하 나갈 수 있게 한다.

이벤트 루프와 콜백 큐(Event Loop&Callback Queue)


코드 실행중 Web API가 가지고 있는 함수가 나온다면, 콜스택은 Web API에게 전달한다.
Web. API에서는 해당 작업을 자체적으로 처리한 뒤 콜백 큐(Callback Queue)로 전달한다. 이렇게 콜백 큐로 들어온 작업들은 콜 스택이 비어있을 경우에만 콜 스택으로 이동하게 되는데 이때 이벤트 루프(Event Loop)가 콜스택이 비어있는지 주기적으로 확인하고 콜백 큐에 있는 작업들을 콜스택으로 이동시키는 역할을 한다.

좋은 웹페이지 즐겨찾기