메모리 구조 (레지스터, 스택, 힙)

Ilhoon·2022년 2월 20일
1

개발자의 기본기

목록 보기
4/6

CPU는 두뇌 메모리는 공책

프로그램 실행 중에 여러 데이터가 공유하는 메모리는 스택, 힙 두 종류

데이터섹션, 코드섹션은 특정 코드 및 데이터 용도로 고정되어있다.


레지스터

CPU안에 있는 저장 가능한 공간 (휘발성)

CPU가 사용하는 저장 공간중에 가장 빠른 저장공간

CPU가 연산을 할때 레지스터에 가져와서 처리한다.

레지스터가 필요한 이유

  • CPU가 메모리에 접근하려면 버스를 타야한다. (시간이 걸린다)
  • 일반적으로 사용하는 메모리인 DRAM은 느림

어셈블리어에서 볼 수 있는 레지스터

  • ebp, esp, eax, ecx 등 모두 레지스터



스택메모리 (정적 메모리)

프로그램(쓰레드)마다 특정용도에 사용하라고 별도로 떼어놔 준 것이 스택 메모리

각 함수에서 사용하는 변수 등을 임시적으로 저장하는 메모리 공간이다.

  • 기본 자료형 변수 (float, char, int, float 등은 모두 스택메모리에 할당)

  • 기본 자료형 매개변수 전달시 스택메모리에 복사본을 만든다 (값형)

    • 배열을 매개변수로 전달하면 배열의 시작 주소값이 스택메모리에저장된다.

      • 배열 요소의 개수를 알 수 없어 스택메모리의 크기를 컴파일시에 결정할 수 없기 때문에!

      • 따라서 매개변수로 전달된 배열의 값을 변경하면 원본이 변경된다.

        void process(int nums[5]){
            size_t i ;
            for (i = 0 ; i < 5; i ++){
                nums[i]  *= 2;			/* 원본 배열의 값이 바뀐다! */
            }
        }

함수에서 사용하는 스택 메모리 크기는 프로그램 컴파일 시에 결정된다. (정적메모리)

스택 메모리의 위치는 실행시에 결정된다. (스택은 큰 주소에서 작은 주소로 쌓인다. 순서대로)

Stackoverflow

  • 스택메모리의 크기는 한정적, 그 이상 사용하려고 하면 발생하는 오류
    • 재귀함수를 너무 깊게 호출하면? 계속 스택메모리를 사용해서 오류
  • 스택메모리를 초과해서 사용해도 오류가 안나는 경우도 있다. (주의해서 사용)
  • 스택메모리 이상의 데이터를 메모리에서 사용하고 싶다면??
    • 동적 메모리 할당 (java에서 new를 통해 선언)

스택메모리 내부

  • ESP : 현재 스택 포인터
  • EBP : 현재 스택프레임의 첫 포인터
  • 스택프레임 : 각 함수가 사용하는 스택 메모리의 범위 (EBP ~ ESP)

  • 함수 호출시 그 함수에서 필요한 바이트만큼 새로운 스택프레임 공간을 잡아준다.
    • 호출한 함수의 명령어 주소도 같이 스택에 저장(함수 반환시 거기로 점프)

장점

  • 할당/해제가 자동으로 관리 된다.

  • 속도가 빠르다

단점

  • 함수가 반환되면 그 안에 데이터가 다 날아감 (전역 변수 혹은 static을 사용해야만 데이터 유지가능)
  • 크기가 컴파일 도중 결정되어 크기가 제한적이다



힙 메모리 (동적 메모리)

가장 범용적인 형태의 메모리 (어디에 누구라도 사용할 수 있는 메모리)

CPU 및 컴파일러가 자동적으로 메모리관리를 안해준다.

프로그래머가 원할 때 원하는 만큼 할당받아서 사용하고 해제할 수 있다.

동적 메모리 : 메모리 할당/해제가 실행 중에 결정된다.

장점

  • 컴퓨터에 메모리 남아있는한 용량 제한이 없다.
  • 프로그래머가 데이터의 수명을 직접제어

단점

  • 메모리 누수의 가능성이 있다. (메모리 할당 후 해제를 안했을 때)

  • 메모리 할당 해제속도가 느리다

    • 스택은 기존에 사용하던 스택프레임 위에 쌓아주는 형태이기 때문에 빈 공간이없고 할당이 간단하다
    • 힙 메모리는 요청한 메모리만큼 빈공간을 찾으려고 이리저리 탐색해야한다
profile
꾸준하게!

0개의 댓글