ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 메모리 구조
    CS 2021. 5. 13. 23:25

    우리가 컴퓨터에서 프로그램을 실행하면 메모리에서 어떤 방식으로 실행되는지를 알아봅시다.

     

    먼저 우리가 프로그램을 실행 시키게 되면

    운영체제(OS)는 보조기억장치(HDD, SSD)에서 해당 정보를 로드하여 메모리(RAM) 라는

    공간에 할당을 해주게 됩니다.

    그리고 메모리에 할당된 작업들이 주기억장치(CPU)가 처리를 하는 형식으로 진행됩니다.

    출처-구글이미지검색

     

    그렇다면 메모리에 할당될때 구체적으로 공간에 할당이 되는지 좀 더 자세히 알아보겠습니다

     

    출처 - TCPSchool.com

    메모리는 크게 코드(code)영역, 데이터(data)영역, 힙(heap)영역, 스택(stack)영역 으로 나뉩니다.

    코드(code)영역으로 갈수록 낮은주소, 스택(stack)영역 으로 갈수록 높은 주소를 사용합니다.

     

    코드(code)영역

    코드영역은 text영역 이라고도 하며 실행되는 프로그램의 코드가 저장되는 영역입니다.

    즉 우리가 작성한 소스코드가 text형식으로 저장되는 영역이라고 할 수 있습니다.

    여기는 소스코드에서 정의 되는 상수, 함수, 제어문 등이 포함될수 있습니다.

    CPU는 코드 영역에서 명령어를 하나씩 가져와 처리를 하게됩니다.

     

    데이터(data)영역

    데이터(data)영역은 static으로 선언된 변수나 전역변수가 저장되는 영역입니다.

    이 데이터들은 프로그램이 시작되면 할당이되고 프로그램이 종료할때 까지 메모리에 남게됩니다.

     

    힙(heap)영역

    힙(heap)영역은 개발자가 직접 할당/해제 하는 메모리 영역입니다.

    즉 개발자가 직접 힙(heap)영역을 관리해야만 하는 영역입니다.

    이렇게 힙(heap)영역에 개발자가 메모리를 할당하는것을 동적할당(Dynamic Memory Allocation) 이라고 합니다.

    힙(heap)영역에는 new 로 생성된 객체나 C에서 malloc()이 힙(heap)영역에 포함됩니다.

     

    힙(heap)영역의 메모리 할당은 프로그램이 실행되는 도중인 런타임(runtime)에 할당을 받게 됩니다.

     

    힙(heap)영역에 개발자 임의로 할당된 메모리들은 기본적으로 프로그램이 종료할때까지 살아있고

    개발자가 해제(회수)를 하지않는 이상 계속 남아있습니다.

    즉 힙(heap)영역에 할당된 메모리는 특정 함수에 구애받지 않고 어디서든 참조가 가능합니다.

     

    만약 개발자가 참조가 끝나 필요없어진 힙(heap)영역의 메모리를 해제(회수)하지않는채 나두면 어떻게 될까요?

    해제되지않는 메모리들은 힙(heap)영역에 남게 되어 쌓이게 되면 메모리가 부족해서

    프로그램에 오류가 발생 할 수 있게 됩니다.

    그러므로 개발자는 힙(heap)영역을 관리해야할 의무가 있습니다.

     

    스택(stack)영역

    스택(stack)영역함수가 호출될때 생성되는 매개변수 와 지역변수(일반변수),포인터(주소값)가 저장되는 영역입니다.

    당연하게도 스택에 들어오는 메모리들은 함수가 호출될때 할당받게 되며 함수의 호출(처리)이 끝나면 사라지게됩니다.

     

    스택(stack)의 구조

    출처 - TCPSchool.com

    기본적으로 스택은 후입선출(LIFO/Last In First Out)의 방식을 가집니다.

    각각의 함수가 호출될때 함수의 대한 정보(매개변수, 반환 주소값 등)이 높은주소에서 낮은 주소쪽으로

    스택에 쌓이게(할당) 됩니다.

    스택에 쌓이는 정보들을 스택프레임(stack frame)이라고 합니다

    출처 - TCPSchool.com

    그리고 후입선출의 방식에 따라 가장 마지막에 호출된 함수부터 작업하게 되며

    완료된 함수는 호출을 종료하게 되며 스택에서 제거됩니다. 이작업은

    스택(stak)에서 main()함수가 종료되면 그만두게 됩니다.

     

    힙(heap)영역과 스택(stack)영역

     

    사실 힙(heap)영역과 스택(stack)영역은 같은 메모리 공간을 쓰고 있습니다.

    힙(heap)영역은 낮은 주소부터 메모리를 할당 시키고

    스택(stack)영역은 높은 주소부터 할당 시킵니다.

     

    만약 힙영역이나 스택영역에서 할당을 시키다가 서로의 영역을 만나 할당 범위를 넘어서면 어떻게 될까요?

    이때 오버플로우(OVER FLOW)가 발생하게 되며 오류가 발생합니다.

     

    이미지 출처 -구글 이미지검색

    힙(heap)영역이 스택영역을 넘어서면 힙 오버플로우 HEAP OVERFLOW 라고하며

    반대로 스택(stack)영역이 넘어서면 스택 오버플로우 STACK OVERFLOW 라고합니다.

     

    그럼 각각의 영역의 장단점을 알아봅시다.

     

    스택(stack)영역

     

    - 매우 빠른 액세스

    ~스택은 기본적으로 지역변수 와 힙(heap)영역에 있는 메모리값의 포인터(주소)만 할당되기 때문에

    빠른 액세스가 가능합니다.

     

    - 변수를 명시 적으로 할당 해제 할 필요가 없습니다.

    ~호출이 끝난 메모리는 자동적으로 없어지기 때문에 따로 할당헤제를 할 필요가 없습니다.

     

    - 스택 크기 제한 (OS에 따라 다름)

    ~스택의 크기는 프로그램이 실행될동안 가변적이지 않고 정해져 있습니다. 이에따라 크기가 부족할수도 있습니다.

     

    - 변수의 크기를 조정할 수 없습니다.

    ~스택에서 할당되는 메모리의 크기는 고정되어 정적으로 할당됩니다. 그렇기 때문에 크기를 조정할순 없습니다.

     

    힙(heap)영역

     

    -효율적인 메모리 관리

    ~동적할당을 통해 메모리 크기를 정할수있기 때문에 효율적인 관리가 가능합니다.

     

    -메모리값이 너무 커서 스택영역에 못들어 갈 때 사용이 가능

    ~힙(heap)영역은 동적할당을 통해 개발자 임의로 메모리의 크기를 지정 할 수 있기때문에 사용이 가능합니다.

     

    -개체의 갯수나 값이 크기가 일정하지않을(가변적일) 때 사용이 가능

    -마찬가지로 동적할당을 통해 크기나 개체의 수가 일정하지 않아도 메모리할당이 가능해 집니다.

     

    -할당작업으로 인한 속도 저하

    ~단지 할당만으로도 속도가 저하 될수 있습니다.

     

    -메모리 직접 관리 해야할 책임

    ~메모리를 직접 할당/해제 를 해야합니다.

     

     

    댓글

Designed by Tistory.