210702_컴퓨터 공학(기초2)

Bitnara Lee·2021년 7월 2일
0

가비지 컬렉션

프로그램에서 더 이상 쓰지 않는 메모리를 자동으로 찾아서 가져가는 것
ex)자바, C#, 자바스크립트 등

트레이싱:

객체에 in-use flag를 두고, 사이클마다 메모리 관리자가 모든 객체를 추적해서 사용중인지 아닌지를 표시(mark), 그 후 표시되지 않은 객체를 삭제(sweep)하는 단계를 통해 메모리를 해제

레퍼런스 카운팅:

한 객체를 참조하는 변수의 수를 추적하는 방법

  • 변수의 레퍼런스가 복사될 때마다 : 레퍼런스 카운트++

  • 객체를 참조하고 있던 변수의 값이 바뀌거나, 변수 스코프를 벗어나면 : 레퍼런스 카운트--

  • if 레퍼런스 카운트 === 0 (아무도 그 객체에 대한 레퍼런스를 가지고 있지 않을 때) : 그 객체와 관련한 메모리는 비울 수 있다

웹 서비스에서의 캐시

캐시

많은 시간이나 연산이 필요한 일에 대해 결과를 저장해두는 것
일시적인(temporarily) 특징이 있는 데이터를 저장하기 위한 목적으로 존재하는, 고속의 데이터 저장공간
-> 캐싱을 사용하면 이전에 검색하거나 계산한 데이터를 효율적으로 재사용

캐시의 데이터는 일반적으로 RAM(Random Access Memory)과 같이 빠르게 액세스할 수 있는 하드웨어에 저장됨

장점

  • 애플리케이션 성능 개선
  • 데이터베이스 비용 절감
  • 백엔드 부하 감소
  • 예측 가능한 성능
  • 데이터베이스 핫스팟 제거
  • 읽기 처리량 (IOPS) 증가

ex)
클라이언트: HTTP 캐시 헤더, 브라우저
네트워크: DNS 서버, HTTP 캐시 헤더, CDN, 리버스 프록시
서버 및 데이터베이스: 키-값 데이터 스토어(e.g. Redis), 로컬 캐시(인-메모리, 디스크)

아마존-캐시설명페이지



Q : 크롬 브라우저 및 node.js의 v8 엔진은, 어떻게 가비지 컬렉션을 하고 있나요?

< V8 엔진의 메모리 구조 >
Resident Set - 실행 중인 프로그램은 V8 프로세스에서 할당된 일정량의 메모리로 표현됨

프로그램이 사용 가능한 것보다 더 많은 메모리를 힙에 할당하려고 할 때 메모리 부족 오류가 발생한다. 힙이 잘못 관리되면 메모리 누수가 발생할 수 있다.

V8 엔진은 가비지 컬렉션을 사용해 힙 메모리를 관리 한다.
참조 없는 객체(orphan object): 스택으로부터 (다른 객체 내부의 참조를 통해) 더 이상 직접 혹은 간접적으로 참조되지 않는 객체

가비지 컬렉터 : V8 프로세스에서 재사용하기 위해 사용되지 않은 메모리를 회수

마이너 GC (Scavenger)

-- New 영역(또는 Young 제너레이션) 관리

스캐벤저(Scavenger) 알고리즘

새 객체에 대한 공간을 예약하려고 할 때마다 증가하는 할당 포인터가 있다.
이 할당 포인터가 New 영역의 마지막에 도달하면, 마이너 GC가 발생한다.

New 영역의 구성: To 영역 / From 영역
대부분의 할당은 To 영역에서 만들어진다(항상 Old 영역에서 할당된 실행 코드와 같은 특정 종류의 객체 제외)-> To 영역이 가득 차면 마이너 GC가 발생한다

메이저 GC

-- Old 제너레이션 영역 관리

Mark-Sweep-Compact 알고리즘

메이저 GC는 Tri-color(흰색-회색-검은색) 마킹 시스템을 사용.
따라서 메이저 GC는 세 단계의 프로세스를 거치며, 세 번째 단계는 조각화 휴리스틱(fragmentation heuristic)에 따라 실행

  • 마킹(Marking): 두 알고리즘의 공통적인 첫 번째 단계로, 가비지 컬렉터가 어떤 객체가 사용중인지 식별한다. 사용중이거나 GC 루트(스택 포인터)에 재귀적으로 도달할 수 있는 객체들은 활성 상태로 표시된다. 마킹은 기술적으로 힙 메모리를 방향 그래프(directed graph)로 간주해 깊이 우선 탐색(depth first search)를 수행한다.

  • 스위핑(Sweeping): 가비지 컬렉터가 힙 메모리를 순회하면서 활성 상태로 표시되지 않은 객체들의 메모리 주소를 기록한다. 이 공간은 이제 사용 가능한 목록(free-list)에서 사용 가능하다고 표시되며 다른 객체들을 저장하는 데 사용될 수 있다.

  • 압축(Compacting): 스위핑이 일어난 다음, 필요하다면 모든 활성 상태의 객체들이 함께 이동될 것이다. 압축 단계는 조각화를 줄이고 새 객체들에 대한 메모리 할당 성능을 증가시킨다.

메이저 GC는 GC를 수행하는 동안 애플리케이션 실행을 멈추므로 stop-the-world GC
라고도 한다.

  1. 많은 마이너 GC 주기를 거치고 Old 영역이 거의 다 찼으며 V8이 "메이저 GC"를 발생시킴.
  2. 메이저 GC는 스택 포인터에서 시작해 재귀적으로 객체 그래프를 순회하면서, Old 영역 내 메모리를 사용한 객체와 남아있는 객체를 가비지로 표시
  3. 동시 마킹이 완료되거나 메모리 제한에 도달하면 GC는 메인 스레드를 사용하여 마킹의 마지막 단계를 수행한다. 이 때 일시 정지 시간이 발생
  4. 메이저 GC는 동시 스위프 스레드를 사용해 모든 참조 없는 객체들의 메모리를 사용 가능한 상태로 표시한다. 또한 조각화를 피하기 위해 관련 메모리 블록을 동일한 페이지로 이동하도록 병렬 압축 작업도 발생한다. 포인터들은 이 세 단계를 통해 갱신된다.

V8 엔진의 구조 및 메모리 관리 방법 잘 설명된 블로그
Memory terminology

profile
Creative Developer

0개의 댓글