ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 콜 스택(Call Stack)
    frontend/javascript&web 2022. 2. 6. 10:10

    Concept By 콜 스택 (Concept By Call Stack)

     

    실행 컨텍스트

    • 현재 실행되고 있는 실행 컨텍스트를 추적하기 위한 구조체

     

    앞서 실행 컨텍스트에 대해 알아 보았으니 그것을 추적하기 위한 구조체인 콜스택에 대해서 예제와 함께 알아보겠습니다.

     

    예시

    function sayAtoB(a,b){ // (1)
    	let message = `${a}님이 ${b}님을 호출하셨습니다.`;
    	return message;
    }
    
    function employee(a,b,func){ // (2)
    	let result func(a,b)
    	return result;
    }
    
    let action = employee("류호진","홍길동",sayAtoB); // (3)
    전역 실행 컨택스트 전역 메모리
      sayAtoB :  fn  (1)
    employee :  fn  (2)
    action : (3)

    위의 실행 컨텍스트에서와 마찬가지로 sayAtoB라는 이름의 함수를 전역 컨텍스트의 메모리에 등록하고 그 후, employee라는 이름을 가진 함수를 전역 컨텍스트 메모리에 등록합니다. 마지막으로 calc의 결과 값을 받을 action 변수를 만들어 줍니다.

    function sayAtoB(a,b){
    	let message = `${a}님이 ${b}님을 호출하셨습니다.`;
    	return message;
    }
    
    function employee(a,b,func){
    	let result = func(a,b)
    	return result;
    }
    
    let action = employee("류호진","홍길동",sayAtoB); // (1)
    전역 실행 컨텍스트 전역 메모리
    employee("류호진","홍길동",sayAtoB) (1) sayAtoB :  fn 
    employee :  fn 
    action :
    함수 실행 컨텍스트 지역 메모리
      a : 류호진
    b : 홍길동
    func :  fn 

    employee 함수를 ()을 이용해 호출합니다. 그럼 함수의 실행 컨텍스트가 새로 만들어 집니다. 이 때 employee 함수의 실행 컨텍스트가 callStack에 쌓이게 됩니다. 자바스크립트 엔진은 현재 내가 실행하고 있는 실행 컨텍스트가 무엇인지 callStack의 top()을 통해서 인지하게 됩니다. 그리고 a, b, func이라는 매개변수에 각 값을 연결해 줍니다.

    function sayAtoB(a,b){
    	let message = `${a}님이 ${b}님을 호출하셨습니다.`;  // (2)
    	return message;
    }
    
    function employee(a,b,func){
    	let result = func(a,b) // (1)
    	return result;
    }
    
    let action = employee("류호진","홍길동",sayAtoB);
    전역 실행 컨텍스트 전역 메모리
    employee("류호진","홍길동",sayAtoB);  sayAtoB :  fn 
    employee :  fn 
    action :
    함수 실행 컨텍스트 지역 메모리
    func("류호진","홍길동"); (1) a : 류호진
    b : 홍길동
    func : fn
    result : (1)
       
    '${a} 님이 ${b} 님을 호출하셨습니다' (2) a : 류호진
    b : 홍길동
    message : 류호진님이 홍길동님을 호출하셨습니다. (2)

    이 후 함수의 내부 코드를 실행하면 func의 결과 값으로 같는 result를 지역메모리에 등록합니다. func도 ()를 만나서 호출되게 되고 그럼 또 func()실행 컨텍스트가 만들어질 것입니다. 콜스택에도 func 실행 컨텍스트가 push됩니다. 이 후 앞선 작업들과 똑같이 a와 b의 매개변수에 값이 연결되고 message라는 변수를 만들어주고 '${a}님이 ${b}님을 호출하셨습니다'의 연산결과가 message에 할당 될 것입니다.

    function sayAtoB(a,b){
    	let message = `${a}님이 ${b}님을 호출하셨습니다.`;
    	return message; // (1)
    }
    
    function employee(a,b,func){
    	let result = func(a,b) // (1)
    	return result;
    }
    
    let action = employee("류호진","홍길동",sayAtoB);
    전역 실행 컨텍스트 전역 메모리
    employee("류호진","홍길동",sayAtoB)  sayAtoB :  fn 
    employee :  fn 
    action :
    함수 실행 컨텍스트 지역 메모리
      a : 류호진
    b : 홍길동
    func :  fn 
    result : "류호진님이 홍길동님을 호출하셨습니다" (1)

    이 후 message가 리턴되어 result에 할당되고 func함수 실행 컨텍스트는 종료되고 콜 스택에서도 pop되어 사라지게 됩니다.

    function sayAtoB(a,b){
    	let message = `${a}님이 ${b}님을 호출하셨습니다.`;
    	return message;
    }
    
    function employee(a,b,func){
    	let result = func(a,b) 
    	return result; // (1)
    }
    
    let action = employee("류호진","홍길동",sayAtoB);
    전역 실행 컨택스트 전역 메모리
      sayAtoB :  fn 
    employee :  fn 
    action : "류호진 님이 홍길동님을 호출하셨습니다" (1)

    이 후 result의 값이 리턴되어서 action에 할당됩니다. action값에 할당되면서 employee 실행 컨텍스트 또한 종료되고 콜스택에서 employee가 pop되어 사라지게 됩니다.

     

    정리하자면, 콜스택의 바닥엔 전역 컨텍스트가 존재하고, 함수가 호출될 때 해당 함수의 실행컨텍스트가 콜스택에 puish되고 함수가 종료되면 pop됩니다.

     

    DeepDive By 콜 스택(DeepDive By Call Stack)

     

    콜 스택

    • 자바스크립트는 단일 스레드 프로그래밍 언어이므로, 하나의 콜 스택만 존재합니다. 즉, 하나의 일만 처리할 수 있다는 뜻입니다. 콜 스택은 여러 함수들을 호출하는 스크립트에서 해당 위치를 추적하는 엔진을 위한 매커니즘이며 현재 어떤 함수가 동작하고 있는지, 그 함수 내에서 어떤 함수가 동작하는지, 다음에 어떤 함수가 호출되어야 되는지를 제어합니다.

     

    콜 스택에 대한 설명

    • 스크립트가 함수를 호출하면 엔진은 이를 콜 스택에 추가하고 함수를 수행합니다.
    • 해당 함수에 의해 호출되는 모든 함수들도 호출 스택에 추가되고 호출이 도달하는 위치에서 실행됩니다.
    • 메인함수가 끝나면 엔진은 스택을 제거하고 메인 코드 목록에서 중단된 실행을 다시 시작합니다.
    • 스택에 할당된 공간보다 많은 공간을 차지하면 stack overflow 에러가 발생하게 됩니다.

     

    사실 우리는 Concepty By CallStack에서 콜스택의 동작에 대한 어느정도 이해를 할 수 있게 되었습니다. 이번 챕터에서는 에러 발생 상황(Throw Error)에서의 콜스택의 동작 및 stack overflow 상황에서는 콜스택 동작을 알아보겠습니다.

     

    function three(){
    	console.log("로그");
    }
    function two(){
    	three();
    }
    function one(){
    	two();
    }
    one();
    콜 스택 PUSH
    콜 스택 POP

    위의 코드는 one이 two를 부르고 tow가 three를 부르면서 실행 컨텍스트가 콜스택에 push되고 push가 끝나면 three부터 pop이 되면서 실행이 됩니다. 하지만 three에서 에러가 발생이 된다면 에러가 발생하고 이후 에러전에 있던 콜스택을 모두 알려주게 됩니다.

     

    function three(){
    	throw Error("에러 삐빅")
    }
    function two(){
    	three();
    }
    function one(){
    	two();
    }
    one();
    call stak throw error

    이제 우리가 개발 중 발생하던 에러 로그가 코드가 순서대로 막 찍혀 있는 것들이 무엇을 의미 하는지 좀 더 자세히 알 수 있을 것이라고 생각됩니다. 또한, 이외에도 무한 재귀함수와 같은 잘못 설계된 함수를 실행하게 되면 함수 실행컨텍스트가 끊임없이 콜스택에 쌓이면서 아래와 같은 모습을 보이게 됩니다.

     

    function infinite(){
    	infinite();
    }
    infinite();
    call stack stack over flow

    콜 스택은 실행 컨택스트의 연장선이라고 볼 수 있습니다. 사실상 모든 자바스크립트의 코어 개념이 이렇게 다이어지는 개념으로 흘러간다고 볼 수 있습니다.

     

    참고 : NHN FRONT-END CONFERENCE

    반응형

    'frontend > javascript&web' 카테고리의 다른 글

    프로토타입(Prototype)  (0) 2022.02.16
    이벤트 루프(Event Loop)  (1) 2022.02.15
    스코프(Scope)  (0) 2022.02.09
    호이스팅(Hoisting)과 클로저(Closure)  (0) 2022.02.08
    실행 컨텍스트(Excution Context)  (0) 2022.02.04

    댓글

Designed by Tistory.