Muscardinus
Call Stack And Memory Heap 본문
JS Engine은 많은 일을 한다. 하지만 그 중에서 가장 핵심적인 2가지 역할을 해준다!
그것은 바로 Reading과 Executing이다.
Reading
정보(변수, 함수 등)를 특정한 장소에 저장
Executing
현재 실행되고 있는 코드를 추적하는 작업
여기서 정보를 저장하는 공간이 바로 Memory Heap이고, 실행 중인 코드를 추적하는 공간이 Call Stack이다.
Memory Heap
Memory Heap은 수 많은 서랍을 가지고 있는 하나의 큰 서랍장이라고 생각하면 된다. 내가 놓고 싶은 물건을 서랍에 넣어두었다가 필요할 때 마다 꺼내쓰기 위한 서랍장이라고 생각해두자. 각각의 서랍에 우리는 변수 및 함수를 저장하는 서랍장이 Memory heap이다.
// tell the memory heap to allocate memory for a number
const number = 11;
// allocate memory for a string
const string = "some text";
// allocate memory for an object and it's values
const person = {
first: "Brittney",
last: "Postma",
};
위 코드에서 보이는 것 들이 Memory Heap에 저장되는 것 들이다.
Call Stack
CallStack은 메모리에 존재하는 공간 중의 하나로, 코드를 읽어내려가면서 수행할 작업들을 밑에서부터 하나씩 쌓고, 위에서 부터 순서대로 작업을 한다. LIFO(Last In First Out) 방식이다.
아마 위 말로는 이해하기가 힘들것이다. 예시를 한번 보자.
function subtractTwo(num) {
return num - 2;
}
function calculate() {
const sumTotal = 4 + 5;
return subtractTwo(sumTotal);
}
debugger;
calculate()
위 코드를 Chrome DevTools에서 실행해보자
1. JS 파일이 실행되면서 동시에 anonymouse라는 함수가 Call Stack의 가장 아래에 들어온다.
2. calculate 함수를 읽음과 동시에 CallStack에서 anonymouse 위에 쌓이게 된다. 그리고 calculate함수 안으로 들어간다.
3. sumTotal값이 저장되고 다음 줄로 진행
4. calculate함수에서 returen 하기 전 subtractTwo함수가 실행 됨으로서 이게 Call Stack에 새롭게 쌓이게 된다.
5. subtractTwo함수 내부에서 num - 2값을 계산한다.
6. subtractTwo함수에서 return하면서 Call Stack에서 탈출한다.
7. calculate 함수 또한 실행에 필요한 모든 값을 얻은 상태이므로 return하면서 Call Stack에서 제거되고 마지막으로 anonymous 또한 Call Stack에서 제거 되면서 모든 수행을 종료한다.
Call Stack을 통하여 우리는 현재 코드가 어디에 위치해 있는지를 추적 할 수 있다는 점을 알 수 있다.
참고로 간단한 변수들은 Call Stack에 저장되며, (객체, 배열, 함수) 등 복잡한 데이터 구조의 값 들은 Memory Heap에 저장된다.
그렇다면 Call Stack 과 Memory Heap의 정상적인 작동에 방해를 주는 요인들은 뭐가 있을까?
Stack Overflow
위의 예시를 보면 알 수 있듯이, CallStack에 작업이 순차적으로 쌓인다. 그러나 만약에 우리가 무한으로 계속 쌓는 작업을 한다면 어떠한 현상이 발생할까? Recursion(재귀 함수)를 실행해보자
위와 같이 stack의 크기 범위를 초과한다는 에러가 뜨게 될 것이다. 이러한 현상을 우리는 Stack Overflow로 한다.
웃긴게 Google에서 recursion을 검색하면 이것을 찾으셨나요?에 이러한 형식으로 계속 나온다.
Garbage Collector
CallStack과 Memory Heap을 배우면서 각각의 공간이 한정적이라는 것을 알 수 있을 것이다. 그렇다면 이 한정적인 공간을 어떻게 해야 효율적으로 사용할 수 있을까? 이를 위해서 자바스크립트에서는 더 이상 효용가치가 없다고 판단되는 변수, 함수 등을 함수 실행 종료 후 메모리 힙에서 제거하는 동작을 수행한다. 필요한 데이터만 Memory Heap에 저장함으로써, 메모리를 더욱 여유롭게 관리한다. 따라서, JS는 Garbage Colleced Language라고도 부른다.
참고로, Garbage Collecer는 Mark And Sweep 알고리즘을 사용하고 있다.
www.geeksforgeeks.org/mark-and-sweep-garbage-collection-algorithm/
Memory Leak
Memory Heap이 제대로 관리되지 않을 경우, 메모리 공간의 범위를 넘어서서 정보들이 저장되는 경우가 생기는데, 이를 Memory Leak이라고 한다. 이는 과거에 사용되었고, 현재는 필요가 없음에도 불구하고 메모리 공간에서 제거되지 않고 공간을 차지하고 있는 현상을 의미한다.
그렇다면 이를 방지하기 위해서는 어떠한 것을 주의해야할까?
1. global scope에서 전역 변수를 많이 만들지 말자
var g = 1;
2. Event Listener의 경우 사용이 완료되면 제거하도록 하자. 제거시키지 않을 경우 계속 Event Listener가 추가되기 때문에 Memory Leak이 발생한다.
var element = document.getElementById("button");
element.addEventListener("click", onClick);
3. setInterval 함수의 사용을 자제하자. setInterval함수의 경우 일정 주기 마다 특정 작업을 수행하도록 지시하기 때문에, 이는 계속 사용 중인 것으로 간주되어 Garbage Collector에 의해서 제거되지 않고 계속 Memory Heap에서 공간을 차지한다.
'FrontEnd > JavaScript Basics' 카테고리의 다른 글
Error Handling (0) | 2020.12.14 |
---|---|
Modules in JS (1) | 2020.12.14 |
Writing Optimized Code (0) | 2020.11.30 |
What is JavaScript Engine? (1) | 2020.11.30 |
this keyword - 마지막 (0) | 2020.10.19 |