일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 자바 프로젝트
- 스택
- React.js
- 비디오 스트리밍
- 파이썬
- 네이버 부스트캠프
- Next/Image 캐싱
- 코딩테스트
- Image 컴포넌트
- 자바스크립트 객체
- 프로그래머스
- 자바스크립트 컴파일
- React ssr
- git checkout
- react
- 멘션 추천 기능
- 파이썬 코딩테스트
- 브라우저 동작
- c++
- beautifulsoup
- PubSub 패턴
- Next.js
- 네이버 부캠
- 웹크롤링
- 자바스크립트
- 네이버 부스트캠프 멤버십
- 파이썬 웹크롤링
- 씨쁠쁠
- Server Side Rendering
- 부스트캠프
Archives
- Today
- Total
코린이의 개발 일지
[JavaScript] 가비지 컬렉션 (Garbage Collection) 본문
반응형
가비지 컬렉션
- 자바스크립트 엔진 내에서는 가비지 컬렉터가 끊임없이 동작한다.
- 가비지 컬렉션은 자바스크립트 엔진이 자동으로 수행하므로 개발자는 이를 억지로 실행하거나 막을 수 없다.
가비지 컬렉션 기준
도달 가능성(reachability)
- 도달 가능한 값은 어떻게든 접근하거나 사용할 수 있는 값을 의미한다.
- 참조 된다고 해서 도달 가능한 것은 아니다. 서로 연결된 객체들도 도달 불가능할 수 있다. ⇒ 루트에서 체이닝으로 도달 가능해야 한다.
도달 가능한 값
- 루트(root)
- 현재 함수의 지역 변수와 매개변수
- 중첩 함수의 체인에 있는 함수에서 사용되는 변수와 매개변수
- 전역 변수
- 기타 등등
- 루트가 참조하는 값, 혹은 체이닝으로 루트에서 참조할 수 있는 값
- 이때 외부로 나가는 참조는 도달 가능한 상태에 영향을 주지 않는다. 외부에서 들어오는 참조만이 도달 가능한 상태에 영향을 준다.
예시
// user엔 객체 참조 값이 저장됩니다.
let user = {
name: "John"
};
- 이때 user를 다른 값으로 덮어 버리면 John은 도달할 수 없는 상태가 되어, 삭제된다.
user = null;
두개의 변수가 같은객체를 가리킬 때
- 만약 두개의 변수가 같은 객체를 가리킬때,
// user엔 객체 참조 값이 저장됩니다.
let user = {
name: "John"
};
let admin = user;
- user를 다른 값으로 덮어도 여전히 admin 변수를 통해 접근 가능하기 때문에 John은 삭제 되지 않는다.
user = null;
외부로 나가는 참조만 있을 때
아래와 같은 상황은 어떨까?
- 외부로 나가는 참조는 도달 가능한 상태에 영향을 주지 않는다. 외부에서 들어오는 참조만이 도달 가능한 상태에 영향을 준다.
- 따라서 John에 저장된 데이터는 외부로 나가는 참조만 있고, 외부에서 들어오는 참조가 없기 때문에 삭제된다.
가비지 컬렉터 내부 알고리즘
mark-and-sweep
- 가비지 컬렉션 기본 알고리즘
가비지 컬렉션 단계
- 가비지 컬렉터는 루트(root) 정보를 수집하고 이를 ‘mark(기억)’ 한다.
- 루트가 참조하고 있는 모든 객체를 방문하고 이것들을 ‘mark’ 한다.
- mark 된 모든 객체에 방문하고 그 객체들이 참조하는 객체도 mark 한다. 한번 방문한 객체는 전부 mark 하기 때문에 같은 객체를 다시 방문하는 일은 없다
- 루트에서 도달 가능한 모든 객체를 방문할 때까지 위 과정을 반복한다.
- mark 되지 않은 모든 객체를 메모리에서 삭제한다.
- 아래 그림을 보면 루트가 참조하고 있는 객체부터 모두 방문하고 한단계씩 depth를 내려가면서(BFS 방식) mark하고 mark되지 않은 모든 객체를 삭제한다.
기본적인 동작은 마킹 → 마킹되지 않은 객체 삭제 이다.
이제 좀더 구체적으로 가비지 컬렉터의 동작 방식을 살펴보자.
메모리 구조(v8 엔진)
힙
힙 영역은 세부적으로 New Space, Old Space, Large Object space, 코드 space, 셀 space, 속성 space, 맵 space로 이루어져 있다.
가비지 컬렉션이 일어나는 부분은 New space와 Old space이므로 이번에는 두 space에 대해서만 알아보자.
- New Space : 새로 만들어진 Object가 저장된다.
- Old Space: New space에서 마이너 가비지 컬렛션이 2번 발생할 동안 살아남은 객체들이 저장된다. 이 영역은 두개로 나눌 수 있다.
- Pointer space: 다른 객체를 참조하는 객체, 즉 다른 개체에 대한 포인터를 가진 객체
- Data space: 문자열, 실수 등의 데이터만을 가진 객체
그럼 GC의 동작방식을 살펴보자
New Space
- 마이너 GC로 관리하는 영역이다.
- 마이너 GC는 객체들의 생명 주기가 짧은 New space에서 빠르게 가비지 컬렉션을 한다.
- Semi space 두개로 나뉘어져 있으며 마이너 GC는 다음과 같이 동작한다.
마이너 GC 동작
- Semi space는 하나는 비어있는 To space, 하나는 객체들이 머무르는 From space이다.
- 마이너 GC가 한번 동작하고 살아남은 객체들은 From space에서 To space로 이동한다.
- 이동할 때, 살아남은 객체들은 연속적으로 이동한다.
- 메모리 단편화를 주기적으로 방지해주는 장점이 있다.
- From space에서 To space로 생존한 객체들의 이동이 완료되면 From space에 남아있는 쓸모없는 객체를 버린다.
- From space와 To space의 역할을 서로 바꾼다.
- 그리고 이후에 또 마이너 GC가 동작할 때, 새로 할당된 객체는 To space로 이동하지만, 기존에 한번 생존했던 4개의 객체는 또한번 생존할 경우 Old space로 이동한다.
Old space
- 메이저 GC로 관리하는 영역이다.
- 메이저 GC는 메모리 사이즈가 큰 Old space에서 가비지 컬렉션을 한다.
- Pointer space랑 Data space 두가지 영역으로 나뉘어 있다.
- 이곳에서 앞서 언급했던 Mark-Sweep-Compact 알고리즘과 Tri-color 알고리즘을 사용하여 가비지 컬렉션을 진행한다.
메이저 GC 동작
- 크게 세가지 단계를 거치는데, 마킹 → 스위핑 → 압축 이다.
- 마킹은 앞서 살펴본 방식이다. 루트부터 시작해서 체이닝으로 도달할 수 있는 깊이까지 dfs로 탐색하여 마킹
- 스위핑은 참조 불가능한 객체 (마킹이 안된 부분)들의 메모리 주소를 free-list라는 자료구조에 추가하는 작업이다. 이 곳에 추가된 메모리 공간은 새로운 객체 저장가능한 주소들이다.
- 압축은 메모리 단편화가 심한 페이지들을 재배치하여 추가적인 메모리를 확보하는 작업이다.
Refs.
https://ko.javascript.info/garbage-collection
https://fe-developers.kakaoent.com/2022/220519-garbage-collection/
반응형
'자바스크립트' 카테고리의 다른 글
[자바스크립트] 제너레이터로 순열, 조합 구현하기 (0) | 2023.09.10 |
---|---|
[JavaScript] 자바스크립트 컴파일과 인터프리팅 (0) | 2023.08.03 |
[JavaScript] 객체 복사 (2) | 2023.02.09 |
[자바스크립트] 실행 컨텍스트 살펴보기 (0) | 2023.02.01 |
[JavaScript] - Prototype(프로토타입) (0) | 2022.09.08 |
Comments