들어가기에 앞서...
운영체제의 역할
- CPU 스케줄링과 프로세스 관리: cpu 소유권을 어떤 프로세스에 할당할지, 프로세스의 생성과 삭제, 자원 할당 및 반환을 관리한다.
- 메모리 관리: 한정된 메모리를 어떤 프로세스에 얼마만큼 할당해야 하는지 관리한다.
- 디스크 파일 관리: 디스크 파일을 어떠한 방법으로 보관할지 관리한다.
- I/O 디바이스 관리: I/O 디바이스들인 마우스, 키보드와 컴퓨터 간에 데이터를 주고받는 것을 관리한다.
프로세스의 메모리 구조
- 스택: 지역변수, 매개변수, 함수가 저장되고 컴파일 시에 크기가 결정된다.
- 힙: 힙은 동적 할당할 때 사용되며 런타임 시 크기가 결정된다.
- 데이터 영역: 데이터 영역은 전역변수, 정적변수가 저장되고, 정적인 특징을 갖는 프로그램이 종료되면 사라지는 변수가 들어 있는 영역이다.
- 코드 영역: 코드 영역은 프로그램에 내장되어 있는 소스 코드가 들어가는 영역이다.
동기적 제어 흐름
- 동기적 제어 흐름은 현재 실행 중인 코드가 종료되기 전까지 다음 줄의 코드를 실행하지 않는 것을 의미한다.
- 분기문, 반복문, 함수 호출 등이 동기적으로 실행된다.
- 코드의 흐름과 실제 제어 흐름이 동일하다.
- 싱글 스레드 환경에서 메인 스레드를 긴 시간 점유하면 프로그램을 멈추게 한다.
비동기적 제어 흐름
- 비동기적 제어 흐름은 현재 실행 중인 코드가 종료되기 전에 다음 라인의 코드를 실행하는 것을 의미한다.
- (자바스크립트에서) 프로미스, 콜백 함수를 호출하는 함수 등은 비동기적으로 실행된다.
- 코드 흐름과 실제 제어 흐름이 다르다.
- 비동기 작업을 기다리는 동안 메인 스레드는 다른 작업을 처리한다.
자바스크립트 엔진과 런타임 환경
자바스크립트 엔진은 하나의 메인 스레드로 동작한다. (싱글 스레드) 메인 스레드는 호출 스택이 하나이기 때문에 한 번에 한 호출만 실행 가능하며 코드를 위에서부터 읽어 한 줄씩 실행한다. 함수를 호출하면 call stack에 메모리 공간이 생기고 함수가 종료되면 call stack에서 삭제된다.
위의 그림은 대다수의 자바스크립트 엔진이 가지고 있는 두 영역이다. 힙heap은 객체가 저장되는 메모리 공간이고, 콜 스택은 실행 컨텍스트가 추가되고 제거되는 곳이다. 콜 스택에 들어오는 코드들은 LIFO(라스트 인 퍼스트 아웃) 순서로 실행되며, 비동기 처리 방식으로 동작하는 몇 가지 함수들을 제외하고는 기본적으로 동기적으로 실행된다.
const foo = () => {};
const bar = () => {};
foo();
bar();
타이머 함수인 setTimeout, setInterval, HTTP 요청, 이벤트 핸들러만 비동기 처리 방식으로 동작한다. setTimeout의 동작 순서를 보자.
var foo = () => {};
var bar = () => {};
setTimeout(foo, 3000);
bar();
블로킹은 싱글스레드에서 시간이 걸리는 작업을 할 때 발생하는 작업 중단을 의미한다. 동기적으로 동작하는 코드에서는 순서대로 처리해야 하기 때문에 블로킹이 발생하지만 setTimeout은 블로킹이 발생하지 않는다. 이와 같이 비동기적으로 동작할 수 있는 것은 자바스크립트가 브라우저 환경에서 실행될 때 이벤트 루프의 도움을 받기 때문이다.
이벤트 루프와 테스크 큐
(API는 Application Programming Interface의 약자로, 소프트웨어 간의 통신하는 방법 정의된 메커니즘이라고 할 수 있다. Web API의 경우 웹 서버와 웹 클라이언트 간의 요청과 응답 등을 처리하는 인터페이스이다.)
Callback queue는 Task queue라고도 불리는데, setTimeout이나 setInterval과 같은 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역이다. Event loop는 브라우저에 내장된 기능이다. 이벤트 루프는 콜 스택이 비면 테스크 큐에 대기 중인 함수를 콜 스택으로 이동시킨다.
var foo = () => {
console.log('foo');
}
var bar = () => {
console.log('bar');
}
setTimeout(foo, 0);
bar();
위 코드를 실행시키면 어떤 결과가 나올까? setTimeout의 시간이 0초로 설정되었음에도 불구하고 bar가 먼저 출력되고 foo가 나중에 출력된다. setTimeout의 콜백 함수 foo는 무조건 테스크 큐에 저장되고, 콜 스택에 있던 bar가 우선 실행되기 때문이다.
'[JavaScript]' 카테고리의 다른 글
[javascript] ES6 최신 문법 2 _ Iteration protocol (0) | 2022.10.12 |
---|---|
[javascript] ES6 최신 문법 1 _ Symbol (0) | 2022.10.12 |
[javascript] 호이스팅(hoisting)과 일시적 사각 지대(TDZ) + var, let, const (0) | 2022.10.05 |
[javascript] 실행 컨텍스트(Execution context)와 클로저(Closure) (0) | 2022.10.04 |
[javascript] prototype과 __proto__ (0) | 2022.10.03 |
댓글