Ch.Covelope

자바스크립트(javascript) - 엔진,런타임,힙,스택,이벤트루프,프로세스 본문

JavaScript

자바스크립트(javascript) - 엔진,런타임,힙,스택,이벤트루프,프로세스

Chrysans 2023. 9. 25. 14:15
반응형
728x90
반응형

 

자바스크립트

 


 

자바스크립트 엔진(javascript engine)

 

JavaScript 엔진은 JavaScript 코드를 해석하고 실행하는 역할을 담당.

 

주요 JavaScript 엔진에는

 V8(Chrome 및 Node.js에서 사용),

 SpiderMonkey(Firefox에서 사용),

 JavaScriptCore(Safari에서 사용),

 Chakra(이전 버전의 Microsoft Edge에서 사용)가 포함.

 


주요 역할

파서 (Parser): 자바스크립트 코드를 읽고 추상 구문 트리(Abstract Syntax Tree, AST)로 변환하는 역할을 한다. AST는 코드의 구조를 표현하며, 엔진은 이를 분석하여 실행에 필요한 정보를 추출한다.

인터프리터 (Interpreter): 변환된 AST를 실행 가능한 명령어로 해석하고 실행.
인터프리터는 코드를 한 줄씩 실행하며, 실행 중에 발생하는 값을 추적하고 제어 흐름을 관리한다.

JIT 컴파일러 (Just-In-Time Compiler): 일부 자바스크립트 엔진은 코드를 실행하기 전에 JIT 컴파일러를 사용하여 중간 코드 또는 기계 코드로 변환. 이렇게 컴파일된 코드는 더 빠른 실행 속도를 제공할 수 있다.

메모리 관리: 자바스크립트 엔진은 동적으로 할당된 메모리를 관리하고 가비지 컬렉션을 수행하여 불필요한 메모리를 해제한다.

스코프와 변수 관리: 엔진은 변수를 저장하고 검색하는 방법을 정의하며, 스코프 체인을 통해 변수의 유효 범위를 관리한다.

 

 


 

 

런타임(runtime)

 

자바스크립트 런타임(JavaScript runtime)은 자바스크립트 코드가 실행되는 환경을 가리킨다. 이 환경은 자바스크립트 코드를 해석하고 실행하는 데 필요한 모든 구성 요소와 라이브러리를 포함. 자바스크립트는 다양한 플랫폼과 환경에서 실행될 수 있으며, 각각의 환경은 자바스크립트 코드를 실행하는 방법과 지원되는 기능들을 정의한다.

 

 

엔진(Engine): 자바스크립트 코드를 해석하고 실행하는 핵심 역할을 담당. 가장 널리 사용되는 자바스크립트 엔진 중 몇 가지는 V8(구글 크롬, Node.js), SpiderMonkey(모질라 파이어폭스), Chakra(마이크로소프트 엣지), JavaScriptCore(애플 사파리) 등이 있다. 각 엔진은 자체적인 특성과 최적화 방법을 가지고 있음.

실행 컨텍스트(Execution Context): 코드 실행 시 변수, 함수, 스코프 등의 정보를 관리. 실행 컨텍스트는 스택(Stack)에 저장되며, 스택 구조를 사용하여 함수 호출과 관련된 정보를 처리한다.

웹 브라우저 환경: 웹 브라우저에서 자바스크립트 코드를 실행할 때 사용되는 런타임 환경. 이 환경은 DOM(Document Object Model)을 조작하고 웹 페이지와 상호 작용하는 데 필요한 API(예: document, window)를 제공한다.

Node.js 환경: 서버 측 자바스크립트를 실행하는 데 사용되는 런타임 환경으로, 파일 시스템 액세스, 네트워크 통신, 데이터베이스 연동 등의 기능을 지원한다. Node.js는 V8 엔진을 기반으로 하며, 서버 애플리케이션 개발에 널리 사용.

런타임 라이브러리 및 모듈: 자바스크립트 런타임 환경은 기본적인 라이브러리와 모듈 시스템을 제공하여 개발자가 코드를 구성하고 재사용할 수 있도록 도와준다. 또한 외부 라이브러리와 패키지를 포함하여 다양한 기능을 확장할 수 있다.

이벤트 루프(Event Loop): 비동기 코드 실행과 이벤트 처리를 관리하는 핵심 메커니즘. 이벤트 루프를 통해 비동기 작업(예: 타이머, 네트워크 요청)이 스케줄링되고 처리된다.

 

 


 

메모리 힙(heap)

 

자바스크립트에서 "메모리 힙"은 동적으로 할당된 데이터를 저장하는 곳. 이곳에는 객체, 배열, 함수 등과 같은 데이터 구조와 값들이 저장된다. 메모리 힙은 자바스크립트 프로그램에서 생성한 모든 객체와 데이터를 보관하고 관리한다.

 

 

메모리 할당 및 해제: 메모리 힙은 자바스크립트 런타임에 동적으로 메모리를 할당하고 해제한다. 이것은 개발자가 수동으로 메모리를 관리할 필요가 없다는 것을 의미. 자바스크립트 엔진은 더 이상 사용되지 않는 데이터를 자동으로 수거하여 메모리를 확보한다.

객체와 데이터 저장: 메모리 힙은 자바스크립트의 모든 객체와 데이터를 저장한다. 이 객체에는 사용자 정의 객체, 내장 객체 (예: 배열, 함수, 문자열), 그리고 DOM 요소 등이 포함.

참조 관리: 자바스크립트에서 객체는 변수에 할당되거나 함수의 매개변수로 전달될 때 참조로 전달된다. 이는 객체가 복사되는 것이 아니라, 객체가 메모리 힙에 저장된 위치를 참조하는 것을 의미. 따라서 여러 변수가 동일한 객체를 가리킬 수 있다.

가비지 컬렉션: 메모리 힙에는 더 이상 사용되지 않는 객체 및 데이터가 쌓일 수 있다. 자바스크립트 엔진은 주기적으로 메모리를 검사하여 더 이상 참조되지 않는 객체들을 수거하는 프로세스를 실행한다. 이러한 프로세스를 가비지 컬렉션이라고 한다.

메모리 누수 방지: 메모리 힙 관리는 개발자에게 중요한 역할을 부여하는데 올바른 코드 작성 및 변수 참조 관리를 통해 메모리 누수를 방지할 수 있다. 더 이상 필요하지 않은 객체에 대한 참조를 해제하고, 큰 데이터 구조를 필요 이상으로 오래 보유하지 않도록 주의해야 한다.

 

 


 

호출 스택(call stack)

 

자바스크립트 호출 스택(call stack)은 코드 실행 중에 함수 호출과 관련된 정보를 저장하는 데이터 구조이다.

이것은 자바스크립트 엔진이 함수 호출을 추적하고, 함수가 실행되는 순서를 관리하는 데 사용된다. 호출 스택은 스택 자료 구조의 일종으로, "Last In, First Out" (LIFO) 원칙을 따른다. 이 말은 가장 최근에 호출된 함수가 가장 먼저 실행되고, 이전에 호출된 함수는 현재 함수가 실행을 마치고 반환될 때까지 대기한다는 것을 의미.

 

 

호출 스택은 다음과 같은 주요 기능과 특징을 갖고 있다.

함수 호출과 반환: 코드 실행 중에 함수가 호출되면 해당 함수의 호출 정보(예: 함수 이름, 매개변수, 지역 변수 등)가 호출 스택에 푸시(push). 함수가 실행을 완료하면 해당 정보가 스택에서 팝(pop)되어 스택에서 제거.

중첩 함수 호출: 함수 내부에서 다른 함수를 호출하는 경우, 호출 스택에 새로운 함수 호출 정보가 추가되며, 이러한 중첩 호출은 스택에 여러 개의 프레임(호출 정보)을 생성할 수 있다.

재귀 함수: 재귀 함수는 자기 자신을 호출하는 함수로 이 경우, 호출 스택에 여러 개의 동일한 함수 호출 정보가 중첩되어 스택의 크기가 커질 수 있다. 재귀 함수는 종료 조건이 필요하며, 종료 조건이 충족되면 호출 스택에서 역순으로 반환된다.

호출 스택은 프로그램의 실행 흐름을 추적하고 오류 메시지를 생성하는 데 도움을 준다. 예를 들어, 무한 루프 또는 스택 오버플로우(호출 스택이 최대 용량을 초과하는 경우)와 같은 오류를 탐지할 때 사용.

코드에서 재귀 호출이나 재귀적인 구조를 사용할 때 호출 스택의 크기에 주의해야 한다.

간단한 호출 스택의 예시:
  함수 A가 호출됨.
  함수 A 내부에서 함수 B가 호출됨.
  함수 B 내부에서 함수 C가 호출됨.
  함수 C에서 반환. 함수 B에서 반환.
  함수 A에서 반환.

A -> B -> C -> C -> B -> A

이러한 호출 순서에 따라 호출 스택에는 함수 A, B, C의 정보가 차례대로 쌓이고 제거된다.

 

 


 

 

콜백 대기열(Callback Queue)

 

자바스크립트에서 "콜백 대기열"은 "콜백 큐" 또는 "이벤트 큐"라고 불린다. 이것은 비동기 코드 실행 및 이벤트 처리에 관련된 중요한 개념 중 하나이다.

 

자바스크립트는 단일 스레드로 작동하며, 동시에 여러 작업을 처리해야 할 때 비동기 프로그래밍이 필요하다.
이 때 콜백 대기열이 사용된다. 예를 들어, 웹 브라우저 환경에서는 사용자의 클릭 또는 네트워크 요청과 같은 이벤트가 발생하면 이벤트 핸들러가 콜백 함수를 큐에 추가하여 나중에 실행되도록 예약.

콜백 큐는 이벤트 루프(event loop)와 함께 작동하여 비동기 작업을 처리한다.
이벤트 루프는 현재 실행 중인 코드가 없을 때 콜백 큐에서 다음 콜백을 가져와 실행하고, 이러한 작업을 반복적으로 수행한다.
이를 통해 자바스크립트는 동시에 여러 작업을 처리할 수 있게 되며, 블로킹되지 않고도 다양한 비동기 작업을 다룰 수 있다.
콜백 대기열 뿐만 아니라 프로미스, async/await와 같은 다른 비동기 패턴도 있으며, 이러한 패턴은 자바스크립트에서 비동기 코드를 더 쉽게 작성하고 관리하는 데 도움을 준다.

 

 


 

이벤트 루프(Event loop)

 

JavaScript 이벤트 루프는 JavaScript에서 비동기 코드 실행을 관리하는 데 중요한 역할을 하는 기본 개념이다. 타이머, I/O 작업 및 이벤트와 같은 비동기 작업이 차단되지 않고 효율적인 방식으로 처리되도록 보장한다.

 

 

  • 스크립트 시작: 스크립트가 실행될 때, 초기 함수 호출(예: 스크립트 자체 또는 이벤트 핸들러)가 호출 스택에 넣어진다.
  • 주 스레드 실행: 주 스레드(main thread)는 현재 함수의 코드를 실행. 이 코드 실행 중에 비동기 작업(예: setTimeout, I/O 작업 또는 이벤트 리스너)를 만날 때까지 진행된다.
  • 비동기 작업 만남: 비동기 작업을 만나면 주 스레드는 가능한 경우 호출 스택에서 다음 함수를 실행(있는 경우).
  • 비동기 작업 백그라운드 실행: 비동기 작업 및 관련 콜백 함수는 외부 컴포넌트(예: 브라우저의 타이머, I/O 시스템 또는 이벤트 시스템)로 전달되어 백그라운드에서 실행된다.
  • 비동기 작업 완료: 비동기 작업이 완료되면 해당 콜백 함수가 콜백 큐에 넣어진다.
  • 이벤트 루프 확인: 이벤트 루프는 지속적으로 호출 스택이 비어 있는지 확인한다. 스택이 비어 있다면, 이벤트 루프는 콜백 큐에서 첫 번째 콜백을 가져와서 호출 스택에 넣는다.
  • 콜백 함수 실행: 콜백 함수가 실행되고, 그와 관련된 코드가 실행된다.

과정 반복: 이벤트 루프는 계속해서 사용 가능한 콜백을 확인하며, 스택이 비어 있을 때마다 콜백을 호출 스택에 넣어 실행.



 

실행 과정

 

어휘 분석(토큰화): JavaScript 엔진은 소스 코드를 토큰이라는 의미 있는 단위로 분해하는 어휘 분석 또는 토큰화를 수행한다. 토큰에는 키워드, 식별자, 연산자 및 기호가 포함된다.


구문 구문 분석(추상 구문 트리 - AST): 엔진은 토큰을 구문 분석하여 추상 구문 트리(AST)를 생성. AST는 코드의 계층 구조를 나타내며 문과 표현식이 서로 어떻게 관련되는지 정의한다.


실행 컨텍스트 생성: 코드를 실행하기 전에 코드 범위에 대한 실행 컨텍스트가 생성. 각 실행 컨텍스트에는 변수 환경이라는 자체 메모리 공간과 외부(부모) 실행 컨텍스트에 대한 참조가 있어 범위 체인(scope chain)이라는 체인을 형성한다.


변수 및 함수 선언: 실행 컨텍스트의 생성 단계에서 변수 선언(var, let 또는 const 사용) 및 함수 선언(함수 표현식이 아닌 함수 선언)이 호이스팅된다. 해당 범위의 맨 위로 이동한다. 변수는 'undefined'으로 초기화(var)되고 함수는 그대로 저장된다.


실행 단계: 코드의 실제 실행이 시작. JavaScript 엔진은 AST를 순회하며 명령문과 표현식을 하나씩 실행.


식별자 확인 및 변수 할당: 엔진이 식별자(변수 이름)를 발견하면 현재 실행 컨텍스트의 변수 환경에서 변수를 조회하고, 찾지 못한 경우 해당 변수를 찾을 때까지 범위 체인(scope chaining)을 계속 진행한다. 변수이거나 전역 범위에 도달한다. 발견되면 그에 따라 값을 읽거나 할당.


함수 실행: 함수가 호출되면 해당 함수에 대한 새로운 실행 컨텍스트가 생성되고 해당 함수 범위 내에서 프로세스가 반복 된다. 매개변수와 지역변수에 메모리가 할당되고, 함수의 코드가 실행된다.


클로저 생성: 클로저는 내부 함수(중첩 함수)가 포함하는(외부) 함수 범위의 변수에 액세스할 때 생성된다. 이러한 클로저는 외부 함수의 실행이 완료된 후에도 외부 범위의 변수에 대한 참조를 유지.


비동기 작업: JavaScript는 타이머(setTimeout, setInterval), I/O 작업 및 이벤트 처리와 같은 비동기 작업을 수행할 수 있다. 비동기 작업이 발생하면 엔진은 이를 외부 구성 요소(예: 브라우저 또는 Node.js 런타임)로 오프로드하여 다른 코드가 계속 실행될 수 있도록 한다.


콜백 실행: 비동기 작업이 완료되면 관련 콜백 함수가 콜백 대기열(작업 대기열)에 배치된다. 이벤트 루프는 콜백 대기열을 지속적으로 확인하고 스택이 비어 있으면 콜백 함수를 실행 스택으로 이동한다. 이를 통해 비동기 코드를 실행할 수 있다.


오류 처리: JavaScript에는 try...catch 블록과 같은 오류 처리 메커니즘이 포함되어 있어 예외를 정상적으로 처리하고 코드 충돌을 방지할 수 있다.


가비지 수집: JavaScript 엔진에는 더 이상 참조되지 않는 객체와 변수를 주기적으로 식별하고 제거하여 메모리를 확보하는 가비지 수집기가 포함.

 

 


 

 

 

https://covelope.tistory.com/

 

Ch.Covelope

Chrys_Code_Develope. https://velog.io/@goggg8822

covelope.tistory.com

 

 

 


 

728x90
반응형
Comments