01_메모리 구조

Lukaid·2023년 9월 10일
0

boostcamp

목록 보기
1/20

메모리 구조 [Memory Structure] 정리

비전공자로서 컴퓨터 공학 지식에 대한 목마름이 항상 있었다. 부캠에 들어와서 이런 이론들을 하나씩 공부할 수 있어서 너무 좋다. 이번에는 메모리 구조에 대해서 정리해보려고 한다.

참고

1. 메모리 구조 (Memory Structure)

메모리는 컴퓨터를 살때, 용량이랑 버전, 실행클럭 정도만 봤지 이렇게 복잡한 구조가 있다는 것은 알지 못했다. 우선 메모리는 다음과 같은 역할과 구성요소를 가지고 있다.

  • 실행파일을 실행시키면 메모리에 로드되면서 코드에서 작성한 동작에 따라 메모리에 데이터들을 쓴다.
  • 메모리는 크게 코드(텍스트)영역, 데이터영역, 힙영역, 스택영역으로 나뉜다.
  • Text: 코드영역, 실행할 프로그램의 코드가 저장되는 영역, CPU는 코드영역에 저장된 명령어를 하나씩 가져가서 처리한다. 힌마디로 명령어들이 저장되는 곳이다. (제어문, 함수, 상수 등)
  • Data: 데이터영역, 프로그램의 전역변수와 정적변수가 저장되는 영역, 프로그램의 시작(main함수 전에)과 동시에 할당되며 프로그램이 종료되면 소멸한다. (전역변수, 정적변수, 배열, 구조체 등), 초기화 된 변수 영역(initialized data segment)과 초기화되지 않은 변수 영역(uninitialized data segment)으로 나뉜다.
  • Heap: 사용자에 의해 관리되는 영역, 사용자에 의해 메모리 공간이 동적으로 할당되고 해제된다. (malloc, calloc, realloc, free, Java나 C++에서 new 연산자로 생성하는 경우 또는 class, 참조 변수 등), 낮은 주소에서 높은 주소로 할당(적재)된다.
  • Stack: 지역변수와 매개변수가 저장되는 영역, 함수의 호출과 함께 할당되며 함수의 호출이 완료되면 소멸한다. (함수의 매개변수, 복귀주소, 지역변수 등), 높은 주소에서 낮은 주소로 할당(적재)된다. 재귀함수의 경우 스택영역이 넘치게 되면 stack overflow가 발생한다. (물론 컴퓨터의 모든 메모리 자원을 이용하는 것이 아닌 OS가 할당해준 Stack 영역의 메모리를 모두 사용했을 때 발생한다.)

2. 메모리 주소 (Memory Address)

32bit 운영체제(x86) 혹은 64bit 운영체제(x64)에 따라 메모리 주소가 달라진다. 오늘날의 대부분의 컴퓨터는 64bit 운영체제(x64)를 사용한다.

32bit 운영체제(x86)의 경우 0x00000000 ~ 0xFFFFFFFF(4GB)까지의 주소를 사용한다. 2^32 = 4GB (그래서 예전 컴퓨터들은 메모리를 4GB 이상 장착해도 4GB만 인식했던 것이다.)
64bit 운영체제(x64)의 경우 0x0000000000000000 ~ 0xFFFFFFFFFFFFFFFF(16EB)까지의 주소를 사용한다. 2^64 = 16EB (이론적으로는 메모리를 16EB까지 장착할 수 있다는 것이다.)
둘의 차이가 상당히 크다.

메모리는 한칸에 1byte의 크기를 가지고 있다. (CS50강의에서도 배웠듯)

운영체제별로 다른 것은 메모리 주소의 크기이다.

32bit 운영체제(x86)의 경우 1byte씩 4번을 묶어서 4byte의 크기를 가지는 주소를 사용한다. (4byte = 32bit)
64bit 운영체제(x64)의 경우 1byte씩 8번을 묶어서 8byte의 크기를 가지는 주소를 사용한다. (8byte = 64bit)

요새 대부분의 운영체제는 64bit 운영체제(x64)를 사용한다.

그래서 정리하자면 메모리 한칸의 크기는 1byte이고 64bit 운영체제(x64)의 경우 8byte씩 묶어서 주소를 사용하고, 그렇기 때문에 포인터(주소를 가르키는 변수)의 크기 또한 8byte이다.

3. 코드와 메모리 영역 (Code and Memory Layout)

아주 중요한 그림이다. 상수, 함수는 Text 영역에, 전역, 정적변수는 Data 영역에, 지역변수들은 Stack 영역에, 동적할당이 되는 변수들은 Heap영역에 위치하게 된다.

Text영역이 가장 낮은 주소, 그다음이 Data영역, 그다음이 Heap영역, 그다음이 Stack영역이다. 이는 포인터로 확인해 볼 수 있다. %p

4. Buffer Overflow

앞선 네개의 메모리 영역중 가장 대표적인게 Heap과 Stack 영역이다. Heap은 사용자가 직접 메모리를 할당하고 해제하는 영역이고, Stack은 함수의 호출과 함께 할당되며 함수의 호출이 완료되면 소멸하는 영역이기에 프로그램을 실행하면서 생성되고 삭제되기 때문이다.

Buffer Overflow가 뭐냐면, 메모리를 할당할 때 메모리의 크기를 정해주는데, 그 크기를 넘어서 메모리를 할당하려고 할 때 발생하는 것 에러가 Buffer Overflow이다.

5. Stack Overflow

이런 Overflow중에 가장 유명한 녀석, Stack Overflow. 말 그대로 Stack영역의 메모리가 넘치면 발생하는 오류다.
호출 스택이 할당 된 스택 영역 경계선 밖으로 넘어갈 때 발생하는데, 보통 가장 흔히 발생하는 경우는 '재귀호출'에서 발생한다.

6. Heap Overflow

Heap Overflow는 힙 영역에서 할당 된 영역의 경계선 밖으로 넘어갈 때 발생하는데, 가장 흔히 발생하는 경우는 매우 큰 데이터를 생성하려고 할 때 발생한다. (예를 들어, 1GB짜리 배열을 생성하려고 할 때, 나는 아직 못겪어본듯?)

자바에서는 OutOfMemory 에러, 메모리 부족을 자주 접한다고 한다.

heap overflow를 방지하기 위한 기법중에 가장 유명한 것이 Garbage Collection이다. (자바에서는 자동으로 해준다고 한다. 파이썬도 자동으로 해줌. js도, c나 c++에서는 동적으로 할당한 메모리를 해제해주는 것을 개발자가 직접 해줘야 한다.)

정리

메모리의 역할과 구성에 대해 간단하게 알아보았다. 메모리는 컴퓨터의 가장 핵심적인 요소인 만큼 이것보다 훨씬 복잡한 내용들이 많은 것으로 알고있다. 하지만 당장에 내가 개발을 할때 꼭 알아야 하는 내용은 위의 내용으로 갈음할 수 있을 것 같다.

profile
풀스택 지향 웹개발자 이성우입니다.

0개의 댓글